Dateihandling Fehlerkorrektur



  • FILE *f;
    char *t = "Hallo Welt";
    
    if( ( f = fopen("test","rb") != NULL ) {
    
       if( fwrite(t,strlen(t),1000,f) == 1000 ) {
           ... //Fehlerbehandlung
       }
    }
    

    Als Beispiel will ich den String "Hallo Welt" 1000 mal in die Datei test reinschreiben.

    Eine Frage muss ich das so machen oder kann ich mir die Fehlerbehandlung auch sparen weil sie niemals vorkommen kann. Weil wenn ich scanf mache gug ich ja auch nicht später ob auch der wert da drin steht oder wenn ich einer Variable was zuweise zb i = 5; if(i != 5 ) perror("blablub"); Ist das überflüssig was ich mache ?
    Wird es schon von den Low-Level abgefangen sodass ich mich darum nicht kümmern muss ?

    Vielen Dank im Voraus



  • da muss stehen fopen("test","wb") und ein fclose(f) fehlt noch.



  • fwrite ( const void * ptr, size_t size, size_t count, FILE * stream );
    

    Den ersten Parameter macht man char t[] , nicht char *t ;

    Der zweite Parameter wird meines Wissens nach mit sizeof() bestimmt, nicht mit strlen();

    Der dritte Paramter ist die Anzahl an Objekten, die geschrieben werden sollen. Nicht die Anzahl, wie oft es geschrieben wird.

    The third parameter of fwrite() is the number of objects to write, not the number of times to write a single object.

    Muss also '1' gesetzt werden.
    Demnach ist der return-Wert auch 1, weil ein Objekt geschrieben wird, und kann nicht auf 1000 abgefragt werden.

    Korrekt wäre also:

    char t[] = "Hallo Welt";
    
    for(int i=0; i<1000; ++i)
        fwrite (t, sizeof(char), sizeof(t), f);
    


  • und sizeof(char) ist nach Definition immer 1



  • stimmt danke wenn ich das so mache wie ich es geschrieben habe habe ich aufeinmal undefiniertes zeug in meiner textdatei stehen.

    P.S man kann es doch mit char * machen dann muss man strlen weil sizeof dann die Größe des Pointers zurückliefern würde bei einem Array ist es besser sizeof zu benutzen.
    korrekt würde es dann so aussehen weil ich muss den Speicher dynamisch reservieren

    fwrite(t,sizeof(char),strlen(t),f)

    Aber meine eigentliche Frage muss ich den Rückgabewert immer beachten ?

    also

    if( fwrite(t,sizeof(char),strlen(t),f) == O ) { ...error }
    

    oder kann ich mir das sparen ist es so wie bei andere streams wie stdin,stdout,stderr ?



  • phanzy schrieb:

    Den ersten Parameter macht man char t[] , nicht char *t ;

    In der Parameterliste ist das dasselbe.

    Vorsicht wenn du strlen benutzt, dann wird das '\0' nicht mitgespeichert

    Ja, du solltest immer auf Fehler prüfen. Denn in dem IO System, dass die libc benutzt könnten auch nach erfolgreichem öffnen einer Datei beim schreiben und lesen Fehler auftreten. (siehe zB unix read(),write())
    Dein Programm sollte nicht verschweigen, wenn Daten nicht geschrieben werden konnten. Somit solltest du nicht nur auf 0 prüfen, sondern auch ob alle Daten geschrieben wurden.

    Auch das schreiben/lesen nach/von stdout,stderr,stdin kann fehlschlagen (i.a. wird dies selten behandelt).



  • Vielen Dank Gary1195,

    hmm das führt zu einer code explosion eine frage habe ich noch

    ich muss ja die Anzahl der Zeichen wissen die in die Datei gespeichert werden sollen bei einem konstanten String ist das klar.

    Aber nehmen wir mal die Fkt

    fprintf(f,%i : NR,nr)

    da ist der String ja nun variabel die größe hängt von nr ab da müsste ich ja quasi erstmal

    char text[1000];
    unsigned int i = 0;
    
    i = snprintf(text,sizeof(text),%i : NR,nr);
    
    if( fprintf(f,"%i : NR,nr) != i ) {
       fclose(f);
       printf("Error");
       return 31;
    }
    

    gibt es eine elegantere Lösung für das Problem ? was ist wenn das array text nicht ausreicht es ist nur 5 stellen groß wie löst man das problem und was haltet ihr von dieser unsauberen Lösung

    i = fprintf(stderr, "%i : NR,nr);
    
    if( fprintf(f,"%i : NR,nr) != i ) {
       fclose(f);
       printf("Error");
       return 31;
    }
    

    Ich glaube die letzte Lösung 😮 👎 👎 👎 ⚠ aber stdin ist zwar auch begrenzt aber die Grenze liegt ganz weit weg



  • phanzy schrieb:

    Der zweite Parameter wird meines Wissens nach mit sizeof() bestimmt, nicht mit strlen();

    Da täuscht dich dein Wissen.
    Bei einem Stringliteral wie vom TO angegeben ist sizeof sogar total verkehrt.

    Und die '\0' muss man bei einer Textdatei eigentlich nicht mit abspeichern.
    Da wäre ein '\n' sinnvoller.



  • @gary1195 und @DirkB:
    Danke, bei den Punkten war ich mir eben nicht ganz sicher 😉

    @TS:
    Wenn du schon ein Anführungszeichen machst bei %i, dann schließe es auch wieder 😃



  • kknd schrieb:

    gibt es eine elegantere Lösung für das Problem ?

    Ja, gibt es:

    Return Value von fprintf schrieb:

    If a writing error occurs, the error indicator (ferror) is set and a negative number is returned.

    Lies dir die Referenz zu fprintf gründlich durch.



  • Danke dirkb dann muss ich nur auf grösser 0 abfragen das macht die sache wesentlich einfacher


Anmelden zum Antworten