fseek auf einer Position jenseits von EOF löst kein EOF mit feof aus, wie kommt es?

Lesezeit: 3 Minuten

Ich lese Daten aus einer Datei in den Speicher, die geöffnet wird mit:

FILE *f = fopen(path, "rb");

Bevor ich anfange, Bytes aus der Datei zu kopieren, suche ich mit:

/**                                                                                                                                                    
 * Goes to the given position of the given file.                                                                                                       
 *                                                                                                                                                     
 * - Returns 0 on success                                                                                                                              
 * - Returns -1 on EOF                                                                                                                                 
 * - Returns -2 if an error occured, see errno for error code                                                                                          
 * - Returns -3 if none of the above applies. This should never happen!                                                                                
 */                                                                                                                                                    

static int8_t goto_pos(FILE *f, uint64_t pos)                                                                                                          
{                                                                                                                                                      
        int err = fseek(f, pos, SEEK_SET);                                                                                                             

        if (err != 0) {                                                                                                                                
                if (feof(f) != 0) return -1;                                                                                                           
                if (ferror(f) != 0) return -2;                                                                                                         
                return -3;                                                                                                                             
        }                                                                                                                                              

        return 0;                                                                                                                                      
}

Das Problem ist, dass, obwohl ich eine Position weit darüber hinaus anstrebe EOFgibt diese Funktion niemals -1 zurück.

Laut Referenz feof sollte einen Wert ungleich Null zurückgeben, wenn EOF angetroffen wird.

Warum ist das? Ist der feof Funktion unbrauchbar?


Beachten Sie, dass ich derzeit den Rückgabewert von verwende fgetc zu prüfen EOF.

  • Wo in den Dokumenten von fseek haben Sie gesehen, dass es das EOF-Flag setzen würde?

    – Matte

    23. Juni 2013 um 18:22 Uhr

  • @Mat: Das OP sagt das nicht explizit …

    – alk

    23. Juni 2013 um 18:27 Uhr


  • @alk: Warum hast du das Bedürfnis, herablassend zu sein? Es hilft weder mir noch sonst jemandem.

    – rzetterberg

    23. Juni 2013 um 21:42 Uhr

  • Ich wollte das nicht persönlich nehmen. Bitte entschuldigen Sie den etwas zynischen Versuch, die Leute zum Lesen der Dokumentation zu drängen. Btw: Im allgemeinen Fall ist es eine gute Idee, die mit dem Tool gelieferte Dokumentation selbst zu drehen, in diesem Fall die Manpages, die mit der Entwicklungswerkzeugkette unter Linux geliefert werden.

    – alk

    24. Juni 2013 um 5:30 Uhr

  • Bei Unsicherheiten ist es immer ratsam, mehr als eine Informationsquelle zu konsultieren. Eine gute Referenz zum “wie es sein soll” ist der Standard: pubs.opengroup.org/onlinepubs/9699919799/idx/functions.html (POSIX), ein Überblick was ist in der GNU libc: gnu.org/software/libc/manual/html_node/… und schließlich können die Manpages hier aus der Quelle gelesen werden: manpages.debian.net/cgi-bin/man.cgi (ohne keine lästige Werbung!)

    – alk

    24. Juni 2013 um 6:50 Uhr


Benutzeravatar von alk
alk

Beim Suchen wird einfach nicht auf das Ende der Datei getestet.

Der Grund dafür ist, dass Sie vielleicht eine machen möchten fwrite() wo du gesucht hast. fseek() kann nicht wissen, was Ihre Pläne sind, nachdem es aufgerufen wurde.

Mach ein fread() nachdem Sie hinter dem Ende der Datei gesucht haben und Sie haben feof() Rückgabe eines Werts ungleich Null.

  • Suchen testet nicht nur nicht auf eof; es löscht das eof-Flag.

    – R.. GitHub HÖR AUF, EIS ZU HELFEN

    23. Juni 2013 um 18:38 Uhr

  • Danke fürs Erklären! Dann feof wird für mich keinen Nutzen haben, da ich benutze fgetc und Überprüfung auf die EOF Rückgabewert sowieso.

    – rzetterberg

    23. Juni 2013 um 21:48 Uhr

  • OP hat den Stream in geöffnet "rb" Modus, das fseek Verhalten macht für schreibgeschützte Dateien keinen Sinn.

    – malat

    23. Januar 2015 um 14:06 Uhr

Das Suchen über das EOF hinaus vergrößert die Datei nach einem nachfolgenden Schreibvorgang, also ist dies konform, im Gegensatz zu dem, was andere glauben. Siehe hier:
fseek

Die Funktion fseek() soll ermöglichen, dass der Dateipositionsindikator über das Ende vorhandener Daten in der Datei hinaus gesetzt wird. Wenn Daten später an dieser Stelle geschrieben werden, sollen nachfolgende Lesevorgänge von Daten in der Lücke Bytes mit dem Wert 0 zurückgeben, bis Daten tatsächlich in die Lücke geschrieben werden.

Deshalb kann fseek EOF nicht zurückgeben. Sie erhalten später ein EOF, wenn Sie versuchen, von einer Position zu lesen, an der zuvor nichts an diese Position oder dahinter geschrieben wurde. Das ist also alles korrektes Verhalten.

feof() wird gesetzt, nachdem ein Leseversuch fehlschlägt, also fgets() oder fread() Vor.

Das Suchen über das Ende der Datei hinaus erhöht bei einigen Betriebssystemen die Größe der Datei. Solange Platz vorhanden ist, um die Datei zu vergrößern, wird niemals ein Fehler zurückgegeben.

1443930cookie-checkfseek auf einer Position jenseits von EOF löst kein EOF mit feof aus, wie kommt es?

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

Privacy policy