Wie verwende ich EOF, um eine Textdatei in C zu durchlaufen?

Lesezeit: 4 Minuten

Benutzeravatar von Tyler Treat
Tyler behandeln

Ich habe eine Textdatei, die in jeder Zeile Zeichenfolgen enthält. Ich möchte eine Zahl für jede Zeile in der Textdatei erhöhen, aber wenn das Ende der Datei erreicht wird, muss sie offensichtlich anhalten. Ich habe versucht, etwas über EOF zu recherchieren, konnte aber nicht wirklich verstehen, wie man es richtig verwendet.

Ich gehe davon aus, dass ich eine While-Schleife brauche, bin mir aber nicht sicher, wie ich das machen soll.

Wie Sie EOF erkennen, hängt davon ab, was Sie zum Lesen des Streams verwenden:

function                  result on EOF or error                    
--------                  ----------------------
fgets()                   NULL
fscanf()                  number of succesful conversions
                            less than expected
fgetc()                   EOF
fread()                   number of elements read
                            less than expected

Überprüfen Sie das Ergebnis des Eingabeaufrufs auf die entsprechende obige Bedingung und rufen Sie dann auf feof() um festzustellen, ob das Ergebnis auf das Erreichen von EOF oder auf einen anderen Fehler zurückzuführen ist.

Verwenden fgets():

 char buffer[BUFFER_SIZE];
 while (fgets(buffer, sizeof buffer, stream) != NULL)
 {
   // process buffer
 }
 if (feof(stream))
 {
   // hit end of file
 }
 else
 {
   // some other error interrupted the read
 }

Verwenden fscanf():

char buffer[BUFFER_SIZE];
while (fscanf(stream, "%s", buffer) == 1) // expect 1 successful conversion
{
  // process buffer
}
if (feof(stream)) 
{
  // hit end of file
}
else
{
  // some other error interrupted the read
}

Verwenden fgetc():

int c;
while ((c = fgetc(stream)) != EOF)
{
  // process c
}
if (feof(stream))
{
  // hit end of file
}
else
{
  // some other error interrupted the read
}

Verwenden fread():

char buffer[BUFFER_SIZE];
while (fread(buffer, sizeof buffer, 1, stream) == 1) // expecting 1 
                                                     // element of size
                                                     // BUFFER_SIZE
{
   // process buffer
}
if (feof(stream))
{
  // hit end of file
}
else
{
  // some other error interrupted read
}

Beachten Sie, dass das Formular für alle gleich ist: Überprüfen Sie das Ergebnis der Leseoperation; wenn es fehlgeschlagen ist, dann auf EOF prüfen. Sie werden viele Beispiele sehen wie:

while(!feof(stream))
{
  fscanf(stream, "%s", buffer);
  ...
}

Dieses Formular funktioniert nicht so, wie die Leute denken, weil feof() wird nicht true zurückgeben, bis nach Sie haben versucht, über das Ende der Datei hinaus zu lesen. Infolgedessen wird die Schleife einmal zu oft ausgeführt, was Ihnen etwas Kummer bereiten kann oder auch nicht.

  • Schön, aber einige Vorschläge dieser beliebten Antwort: 1) „Funktion: fscanf()Ergebnis bei EOF oder Fehler: Anzahl erfolgreicher Konvertierungen geringer als erwartet” entspricht einem eingegebenen “Fehler” mit Formatkonvertierungsfehlern. Keine korrekte Gruppierung IMO. Schlagen Sie eine andere Spalte vor, OTOH ist eine komplizierte Funktion 2) Rechtschreibprüfung 3) Schlagen Sie “schlechter Code ” kommentieren while(!feof(stream)) Beispiel.

    – chux – Wiedereinsetzung von Monica

    6. November 2015 um 20:38 Uhr


Eine mögliche C-Schleife wäre:

#include <stdio.h>
int main()
{
    int c;
    while ((c = getchar()) != EOF)
    {
        /*
        ** Do something with c, such as check against '\n'
        ** and increment a line counter.
        */
    }
}

Im Moment würde ich es ignorieren feof und ähnliche Funktionen. Die Erfahrung zeigt, dass es viel zu einfach ist, es zum falschen Zeitpunkt anzurufen und etwas zweimal zu bearbeiten, in dem Glauben, dass eof noch nicht erreicht ist.

Zu vermeidende Falle: Verwenden char für den Typ c. getchar gibt den nächsten Charaktercast an an zurück unsigned char und dann zu einem int. Dies bedeutet, dass auf den meisten [sane] Plattformen der Wert von EOF und gültig“char„Werte ein c Überlappen Sie sich nicht, damit Sie es nie versehentlich entdecken EOF für einen “normalen” char.

  • Siehe meine Antwort Ich habe ein eof definiert

    – Straßenparade

    2. Dezember 2009 um 21:56 Uhr

  • @streetparade: Inwiefern?

    – CB Bailey

    2. Dezember 2009 um 21:59 Uhr

  • Ein gültiger Zeichenwert von getchar kann noch nie überlappen mit EOF auf jeder konformen Plattform, da Zeichen von zurückgegeben werden getchar liegen im Bereich von unsigned int (daher nicht negativ) und EOF muss negativ sein.

    – Café

    2. Dezember 2009 um 22:48 Uhr

  • @caf: Das dachte ich, bis ich darauf hingewiesen wurde, dass es Plattformen mit 32 Zeichen und 32 Ints gibt. Das bedeutet, dass char -> unsigned char -> int negativ werden kann. Somit ‘[sane]’.

    – CB Bailey

    2. Dezember 2009 um 22:51 Uhr

  • Ach ja, und gute Ratschläge zum Ignorieren feof – Nach meiner Erfahrung weist die Verwendung dieser Funktion fast immer auf einen Fehler hin. Das Testen des Rückgabewerts des letzten Eingabefunktionsaufrufs ist in 99 % der Fälle ausreichend und korrekt.

    – Café

    2. Dezember 2009 um 22:51 Uhr

Benutzeravatar von Nematollah Zarmehi
Nematollah Zarmehi

Sie sollten den EOF nach dem Lesen aus der Datei überprüfen.

fscanf_s                   // read from file
while(condition)           // check EOF
{
   fscanf_s               // read from file
}

Ich würde Ihnen vorschlagen, fseek-ftell-Funktionen zu verwenden.

FILE *stream = fopen("example.txt", "r");

if(!stream) {
    puts("I/O error.\n");
    return;
}

fseek(stream, 0, SEEK_END);
long size = ftell(stream);
fseek(stream, 0, SEEK_SET);

while(1) {

    if(ftell(stream) == size) {
        break;
    }

    /* INSERT ROUTINE */

}

fclose(stream);

1398070cookie-checkWie verwende ich EOF, um eine Textdatei in C zu durchlaufen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy