ifstream und get() unerwartetes Verhalten



  • Hallo zusammen,

    Ich habe eine Text datei wo eine Zeile wie:

    2345 012345678901234

    steht. Nach dem letzten ziffer steht keine escape zeichen, keine newline oder
    sonst was anderes...

    Wenn ich mit Hilfe von ifstream::get() die Zeile in meine buffers einlese, kriege ich von dem zweiten buffer unerwartete Zeichenausgabe..

    unsigned counter ;
    char receiver_buffer[16];
    char control ;
    ifstream* portfile ;
    // ..
    
    // Parse Zweiter Teil = 012345678901234    max laenge 15 chars
    for(counter=0 ; counter<sizeof(receiver_buffer)-1 ; counter++){
     if((control = portfile->get()) == ' ' )   // lese zeichen fuer zeichen ein
       break ;                                 // space getroffen: wir 'haben' fertig
    
     receiver_buffer[counter] = control ;
    }
    
    cout <<  receiver_buffer <<endl;
    

    Die schleife wird 15 ausgefuehrt. Bei jedesmal lese ich via ifstream::get() ein
    char ein. Bei dem letzten Durchgang, bin ich an dem letzten Zeichen und noch
    nicht am "eof". Die schleife wird verlassen ohne eof check zu benoetigen...

    Was aber dabei rauskommt:

    012345678901-234

    Das letzte Character wird dabei voellig daneben geparst. Dasselbe code habe
    ich an einer anderen Maschine compiliert. Das Parsen funktioniert tadellos:

    012345678901234

    Macht get() nichts anderes als ein zeichen zu lesen und den iterator in
    der Datei zu naechstem char zu bewegen? Ich kann mir vorstellen dass er beim
    letzten Char rueckgabe, den eof bit einsetzt. Aber wieso kriege ich trotzdem
    solche Zeichen wenn ich schon die Schleife verlassen habe?

    Danke im voraus,



  • Du solltest zuerst deinen Puffer mit Nullen füllen (oder zumindestens abschließend eine Null setzen):

    char receiver_buffer[16] = { 0 };
    
    // bzw. vor der Ausgabe
    receiver_buffer[15] = '\0';
    

    Ansonsten hast du irgendeinen undefinierten C-String (denn die Ausgabe endet erst beim ersten (binären) Null-Zeichen)...

    P.S: Mit std::string wäre dir das nicht passiert -)



  • Hallo,

    Th69 schrieb:

    Du solltest zuerst deinen Puffer mit Nullen füllen (oder zumindestens abschließend eine Null setzen):

    char receiver_buffer[16] = { 0 };
    // bzw. vor der Ausgabe
    receiver_buffer[15] = '\0';
    

    Ansonsten hast du irgendeinen undefinierten C-String (denn die Ausgabe endet erst beim ersten (binären) Null-Zeichen)...

    Das erklaert schon mal alles. Danke.

    Was mich als zweites interessiert ist, dass dasselbe Code an einem anderen
    Maschine ohne oben geschildertes Problem ausgegeben wird. Es sieht so aus,
    als ob dieser compiler automatisch die Elemente des Arrays auf '\0' setzt, oder?
    Anders kann ich mir nicht vorstellen..Gibt's einen Weg solche Unterschiede
    zwischen Compilern festzustellen?

    Danke,



  • jsbach schrieb:

    Es sieht so aus, als ob dieser compiler automatisch die Elemente des Arrays auf '\0' setzt, oder? Anders kann ich mir nicht vorstellen..Gibt's einen Weg solche Unterschiede zwischen Compilern festzustellen?,

    Kann genauso gut Zufall sein. Einen nicht null-terminiertes char Array als C-String zu behandeln ist ein Programmmierfehler. Genauso wie das Semikolon am Ende einer Anweisung zu vergessen, nur das der Kompiler diesen Fehler nicht feststellen kann. Wenn du also wirklich mit C-Strings arbeiten musst, musst du dich auch darum kümern, dass sie zu jedem Zeitpunkt, an denen du sie benutzt, auch brauchbar sind (passende Länge, null-terminiert). std::string nimmt dir all diese Arbeit ab.

    Gruß
    Don06


Anmelden zum Antworten