File einlesen und in ein Struct speichern



  • @Ashtari sagte in File einlesen und in ein Struct speichern:

    Könntest du mir noch erklären, warum feof, strchr und getc "unnütz oder falsch" sind?

    Deine Benutzung von feof war falsch. Dieses hier:

    while (!feof(openFile))

    funktioniert nicht. Dass man am Dateiende ist, erkennt feof erst NACHDEM du versucht hast, über das Ende hinaus zu lesen (außer in Pascal, da ist das anders). Wenn du dich also direkt am Ende befindest, ist das eof noch false, obwohl kein weiteres Zeichen gelesen werden kann.

    Korrekt ist:

    • Versuche zu lesen
    • Teste, ob das Lesen erfolgreich war - wenn ja, dann verarbeiten

    Falsch ist:

    • Teste, ob der Dateistream ok ist
    • Wenn ja, dann lesen & verarbeiten


  • Dieser Beitrag wurde gelöscht!


  • Mal eine weitere Frage zu ähnlichem Problem...

    Ich möchte jetzt ein .bin.ascii File mit ähnlichem Aufbau, aber anderem Inhalt einlesen.

    Die File hat den Aufbau ( | ist der Trenner der Spalte):
    Nummer | Name | anzahl vorhanden |anzahl benötigt
    1 | 'Getraenk Fanta' | 0 | 12

    Dabei ist der Name immer innerhalb zwei Hochkommata und die Beschreibung des Produkts (also Getraenk zB. oder Alkohol usw.) mit zwei Leerzeichen zum Produktnamen getrennt.

    Nummer ist ein Integer Wert (von 1 bis < 2000), Name ist, so vermute ich, ein char, anzahl vorhanden und anzahl benötigt wieder Integer Werte, beide können dreistellig werden (also < 999).

    Das Ganze möchte ich in folgendem Struct speichern...

    struct getraenk
    {
        int nummer;
        char nameGetraenk[100];
        int anzahlVorhanden;
        int anzahlBenoetigt;
    };
    

    Jetzt habe ich es, ähnlich wie oben gemacht..

    #define BUFFER 100
    ...
    int einlesenGetraenkeListe(char *file_arr)
    {
        FILE *openFile = fopen(file_arr, "r");
        char z(BUFFER);
        struct getraenk getraenk1;
    
        while(fgets(z, BUFFER, openFile))
        {
            if (4 == sscanf(z, "%d %s %d %d", &getraenk1.nummer, getraenk1.nameGetraenk, &getraenk1.anzahlVorhanden, &getraenk1.anzahlBenoetigt))
            {
                printf("Getraenkename ist: %d\n", getraenk1.nameGetraenk);
            }
        }
    }
    

    Die Ausgabe klappt dabei aber nicht so.. Nehme ich das o.g. Beispiel (...sscanf(z, "%d %s %d ....)) erhalte ich keine Ausgabe..
    Wenn ich jetzt aber das s in ein d ändere, also als signed int anzeigen lasse, dann erhalte ich einen output (in jeder Zeile 6422028...)

    Ich verstehe nicht ganz wo der Fehler liegt, denn mit dem ersten Struct hat es wunderbar funktioniert und nach dem gleichen (naja, ähnlichem - ich habe ja ein char in meinem struct was ich jetzt mit "zuordnen" möchte) Muster geht es jetzt nicht.

    Herzlichen Dank für eure Hilfe vorab.



  • @Ashtari Sind da wirklich runde Klammern in Zeile 6?

    Sind in der Datei die | enthalten oder hast du das nur für uns gemacht?

    scanf überliest bei %s führende Leerzeichen und dann weiter bis zum nächsten Leerzeichen.
    Da wäre '%[^']' statt des %s nötig. (vor dem ersten ' ist noch ein Leerzeichen)

    Du kannst auch mal z ausgeben.



  • int einlesenGetraenkeListe(const char *file_arr)
    {
        FILE *openFile = fopen(file_arr, "r");
        char z[BUFFER];
        struct getraenk getraenk1;
    
        while(fgets(z, BUFFER, openFile))
        {
            if (4 == sscanf(z, "%d%*[^']'%[^']'%*s%d%*s%d", &getraenk1.nummer, getraenk1.nameGetraenk, &getraenk1.anzahlVorhanden, &getraenk1.anzahlBenoetigt))
            {
                printf("Getraenkename ist: %s\n", getraenk1.nameGetraenk);
            }
        }
        fclose(openFile);
    }
    


  • Hallo @DirkB , Hallo @Wutz ,

    danke für eure Hilfe - mit der Lösung von Wutz hat es hin gehauen.

    Ein - %[^']' - bewirkt dann quasi, dass Leerzeichen vor dem Hochkommata "übersprungen" werden?



  • @Ashtari sagte in File einlesen und in ein Struct speichern:

    Hallo @DirkB , Hallo @Wutz ,

    Ein - %[^']' - bewirkt dann quasi, dass Leerzeichen vor dem Hochkommata "übersprungen" werden?

    Nein, das bewirkt schon ein Leerzeichen im Formatstring
    %[^'] Liest alles, bis auf ' ein. (Das ^ schließt Zeichen aus)
    Es wird also Alles bis auf das Hochkomme eingelesen. Deswegen steht es dahinter nochmal.

    danke für eure Hilfe - mit der Lösung von Wutz hat es hin gehauen.

    Ich sehe da Probleme, wenn zwischen den | und den Zahlen kein Leerzeichen (oder ähnliches) ist.



  • @DirkB sagte in File einlesen und in ein Struct speichern:

    danke für eure Hilfe - mit der Lösung von Wutz hat es hin gehauen.

    Ich sehe da Probleme, wenn zwischen den | und den Zahlen kein Leerzeichen (oder ähnliches) ist.

    Sorry, hatte vergessen oben auf deine Fragen zu antworten.
    Die Spalten sind mit Leerzeichen getrennt - ich hatte es in der Frage nur als optischen Trenner genutzt damit ihr es besser erkennen könnt.. Führte dann am Ende wohl eher zu Verwirrungen.

    Die Daten werden getrennt durch Leerzeichen, sodass eine Zeile dann ungefähr so aussieht...

    123 'Getraenk Cola' 0 12
    (Edit: bekomme keine weiteren Leerzeichen dazwischen, es sind aber zwischen 2 und 5 Leerzeichen zwischen den Spalten)

    Mit deiner Erklärung zu %[^'] sollte es also klappen, da es den Text, ausgenommen der Hochkommata einliest, bis zu dem nächsten Leerzeichen.

    Danke nochmals und schöne Ostertage 🙂


  • Mod

    @Ashtari sagte in File einlesen und in ein Struct speichern:

    Ein - %[^']' - bewirkt dann quasi, dass Leerzeichen vor dem Hochkommata "übersprungen" werden?

    Nein, überhaupt nicht. Lies die Erklärungen und die Anleitung! scanf sollte man als C-Programmierer schon halbwegs beherrschen.

    Erstmal kann das kein Ausdruck zum Überspringen von irgendwas sein, denn da steht ein Prozentzeichen und das ist für scanf der Trigger, dass da auch tatsächlich etwas gelesen und in einer Variablen gespeichert werden soll. Was das ist, dafür müssen wir die Bedeutung des nächsten Zeichens nachgucken, also [. Da steht in der Anleitung zwar etwas vonwegen, dass dies ein Scanset wäre, aber da wir die Anleitung ja hoffentlich gründlich gelesen haben, wissen wir, dass hier ein Sonderfall vorliegt, weil das übernächste Zeichen ein ^ ist, und wir daher ein negiertes Scanset haben. Also wird eine Zeichenkette gelesen, die alles außer dem enthält, was zwischen [^ und ] steht. Also hier alles außer einem Hochkomma. Und das war dann das, worauf das % sich bezog. Das nächste Zeichen, ebenfalls ein Hochkomma gehört dann schon nicht mehr zu dem Prozentausdruck, gibt also Zeichen an, die überlesen werden sollen, ohne sie irgendwo zu speichern. Es soll hier also das Hochkomma übersprungen werden, bei dem das vorher negierte Scanset gestoppt hat.

    PS: Wie tippe ich im Forum eigentlich ein einzelnes Hochkomma in Code-Formatierung? Drei Hochkommata nacheinander bringen die Formatierung komplett durcheinander, und auch mit Backslashes habe ich keine funktionierende Variante gefunden



  • Dieser Beitrag wurde gelöscht!

Anmelden zum Antworten