Dateiende erkennen



  • Hallo Sepp,
    vielen Dank für deine ausführliche Antwort.
    Natürlich schreibe ich in C, irgendwie bin ich gestern wohl durcheinander gekommen oder es war schon zu spät 😮 .
    Und ja du hast richtig erkannt das alle Datensätze gleich groß sind.
    Ich habe gehofft das ich solange die Zeilen zählen kann, bis keine Datensätze mehr vorhanden sind. Aber du hast natürlich recht, meine Schleife kann so nicht Funktionieren.



  • Dieser Thread wurde von Moderator/in SeppJ aus dem Forum C++/CLI mit .NET in das Forum C (alle ISO-Standards) verschoben.

    Im Zweifelsfall bitte auch folgende Hinweise beachten:
    C/C++ Forum :: FAQ - Sonstiges :: Wohin mit meiner Frage?

    Dieses Posting wurde automatisch erzeugt.


  • Mod

    das_blinker schrieb:

    Und ja du hast richtig erkannt das alle Datensätze gleich groß sind.
    Ich habe gehofft das ich solange die Zeilen zählen kann, bis keine Datensätze mehr vorhanden sind.

    Möglich wäre das, aber ein bisschen umständlich. Denn das Zählen der Zeilen ist gleichbedeutend mit Auslesen der Datei, also kannst du auch gleich richtig auslesen und dabei mitzählen, wie viele Datensätze du gelesen hast. Speicher dynamischer Größe zum Speichern von Daten kann man in C mittels der malloc-Funktion (oder einer ihrer Varianten) erhalten. Mittels realloc kann die Größe dieses Bereichs dann auch nachträglich noch verändert werden. Das ist der entscheidende Trick, wieso man die Anzahl der Datensätze nicht unbedingt im Voraus kennen muss.

    Oder aber du holst dir die Größe der Datei und teilst diese durch die Größe eines einzelnen Datensatzes. Die Größe einer Datei kann man erhalten, ohne die Datei komplett auszulesen. Entweder durch Betriebssystemfunktionen (stat ist auf praktisch allen Systemen vorhanden und kompatibel) oder indem du ans Ende der Datei springst und dir den Wert des Lesezeigers holst (fseek/ftell). Dann holst du dir (wieder mittels malloc) genügend Speicher für alle Datensätze und kannst dann mittels fread¹ in einem Rutsch alles auslesen.

    ¹: Bei der Gelegenheit fällt mir übrigens auf, dass du das fread in deinem Beispiel falsch benutzt. Guck dir noch einmal die Parameter und ihre Bedeutung an.



  • du könntest auch steuerzeichen verwenden, also z.b. 00



  • Für was?



  • Hallo SeppJ

    Was ist mit

    while ( (c = fgetc(fz))  != EOF)
    {
      lies(daten);
      verarbeite(daten);
    }
    

    das ginge eher oder?


  • Mod

    rustyoldguy schrieb:

    Hallo SeppJ

    Was ist mit

    while ( (c = fgetc(fz))  != EOF)
    {
      lies(daten);
      verarbeite(daten);
    }
    

    das ginge eher oder?

    Nein, dein Vorschlag produziert doch exakt die gleiche Problematik.



  • Dann bleit dir nix anderes übrig, als etwa mit

    currentposition = ftell(fz);  
    filelength = lseek(fh, 0, SEEK_END);  
    position = lseek(fh, currentposition, SEEK_SET);
    

    zuerst die Dateilänge zu bestimmen, um dann
    die Anzahl der Datensätze zu berechnen, welche
    dann den Lesevorgang mit einer for-Schleife
    vornehmen


  • Mod

    Tja, ein unlösbares Problem also. Wenn es doch bloß möglich wäre, festzustellen, ob eine Leseaktion erfolgreich war. Sollte mal jemand erfinden, so etwas.

    🙄



  • das_blinker schrieb:

    Und ja du hast richtig erkannt das alle Datensätze gleich groß sind.

    Da du keine Zeilen benutzt sondern Datensaetze, die auch noch immer gleich groß sind, waren deine Ansätze
    - Verwendung einer Struktur
    - Verwendung von fread
    schon richtig und wenn du das dir alleine erarbeitet hast spricht einiges für deine Auffassungsgabe, es hapert bei dir nur noch im Verständnis von Zeigern und realloc.
    Lass das fopen_s sein, jeder vernünftige Mensch benutzt fopen zumal du fopen_s falsch auswertest.

    typedef struct Artikel Artikel;
    	Artikel *tabelle = 0, artikel;
    	int i=0;
            ...
    
    	while (fread(&artikel, sizeof(artikel), 1, stream)==1)
    	{		
    		i++;
    		tabelle = realloc(tabelle,i*sizeof*tabelle);
    		tabelle[i-1] = artikel;
    	}
    
    	fclose(stream);
    	free(tabelle);
    

    Mit realloc vergrößerst du also immer bei Bedarf deine tabelle um einen Elementplatz, am Ende free nicht vergessen.
    Je nach Implementierung arbeitet realloc unterschiedlich "optimal", für deine Zwecke und wenige tausend Aufrufe meistens völlig aussreichend, bei Bedarf gibt es einfache manuelle Optimierungsvarianten.


Anmelden zum Antworten