2012-06-15 8 views
9

In dem Buch Überprüfung Linux-System Programmierung Ich habe einige wie folgt lesen:fgetc, EOF

fgetc gibt die als unsigned char Guss lesen Charakter einer int oder EOF auf Dateiende oder Fehler. Ein häufiger Fehler fgetc Verwendung ist:

char c; 
if ((c = fgetc()) != EOF) {...} 

Die richtige Version dieses Codes ist:

int c; 
if ((c = fgetc()) != EOF) { printf("%c", (char)c); ... } 

Also, warum nicht ich warf einen Rückgabewert char vor mit EOF vergleichen? Warum muss ich EOF genau mit int vergleichen? Wie EOF definiert als -1, ist es nicht normalerweise zu char gegossen?
Gibt es Plattformen/Compiler, wo es nicht stimmt?

+0

möglich duplikat von ["while (! Feof (datei))" ist immer falsch] (http://stackoverflow.com/questions/5431941/while-feof-file-isal-ways-wrong) – jww

+0

@jww: Diese Frage verwendet nicht 'feof()', also ist es kein Duplikat von "[' while (! feof (Datei)) 'ist immer falsch] (http://stackoverflow.com/questions/5431941/what-feof- Datei-ist-immer-falsch) ". –

Antwort

10

Sie können den Rückgabewert nicht an char übergeben, da der Rückgabewert EOF und EOF sein kann. Der Wert ist systemabhängig und nicht mit einem gültigen Zeichencode identisch. link

Normalerweise ist es -1, aber Sie sollten nicht davon ausgehen.

prüfen diese große Antwort vom c-faq-site:

Zwei Fehlerarten möglich sind, wenn, wie im Fragment oben, Rückgabewert der getchar auf ein Zeichen zugeordnet ist.

  1. Wenn Typ char signiert ist, und falls EOF definiert ist (wie es üblich ist) als -1, die Zeichen mit dem Dezimalwert 255 ('\ 377' oder '\ xff' in C) wird vorzeichenerweiterte und wird vergleichbar mit EOF, vorzeitig den Eingang zu beenden. (Annahme von 8 Bits char).

  2. Wenn type char unsigned ist, ein tatsächlicher EOF-Wert wird abgeschnitten (durch mit seinen höherwertigen Bits verworfen, wahrscheinlich in 255 oder 0xFF) resultierenden und nicht als EOF erkannt werden, in resultierenden effektiv unendlichen Eingang.

Hoffe, es hilft!

Edited: (der @FatalError Kommentar zu dieser Antwort hinzugefügt, dies auf der c-faq Website erklärt aber das sieht mehr mir klar)

„Wenn du es dann werfen verkohlen nimmt EOF die Derselbe Wert wie ein gültiges Zeichen und daher von diesem Zeichen nicht unterscheidbar. Dies allein sollte ausreichen, um das Ergebnis nicht als char "@FatalError-Kommentar zu verwenden.

+0

also was? Ich verstehe nicht. nach Casting wird gleich "-1" sein, nicht wahr? – pproger

+0

mein Zeichen ist nicht vorzeichenlos, ich gab Ihnen eine Beispielcode. – pproger

+0

@pproger Der Standard schreibt tatsächlich nicht vor, ob 'char' allein signiert oder unsigniert ist. Wenn Sie ein garantiert signiertes Zeichen benötigen, müssen Sie 'signed char' verwenden. – Corbin

3

Es gibt zwei Möglichkeiten, wenn Sie den Wert auf einen char zuweisen, bevor mit EOF Vergleich:

  • char ein signierter Wert ist. In diesem Fall gibt es ein legitimes Zeichen (oft SM, KLEINER LINKER BRIEF MIT DIAERESE, U + 00FF), das fälschlicherweise als EOF interpretiert wird.
  • char ist ein vorzeichenloser Wert. In diesem Fall wird EOF in 0xFF übersetzt und dann zu int als positiver Wert befördert, der niemals mit EOF gleichgesetzt wird, was ein negativer Wert ist.

Wie auch immer, das Programm wird sich manchmal schlecht benehmen.

Es gibt (oder, genauer gesagt, war es so) eine Chance auf einen Compilerfehler, so dass die Zuweisung korrekt erfolgte, aber der zugewiesene Wert nicht für den Vergleich verwendet wurde. Das würde dazu führen, dass der Code OK zu sein scheint, auch wenn dies nicht der Fall ist. Glücklicherweise ist das kein Problem in einem modernen Compiler.