C-Strings Nullzeichen (\0)



  • Ist es bei C-Strings wichtig das Nullzeichen "\0" mit anzuhängen?

    Beide Codes funktionieren bei mir:
    Mit Nullzeichen

    #include <iostream>
    using namespace std;
    
    int main()
    {
        char n[60]="Hallo Welt\0";
    
        return 0;
    }
    

    Ohne Nullzeichen

    #include <iostream>
    using namespace std;
    
    int main()
    {
        char n[60]="Hallo Welt";
    
        return 0;
    }
    

    Ich hab jetzt schon in mehreren Büchern gelesen das man an das Ende eines C-Strings immer ein Nullzeichen anhängt, ist das aber auch wirklich nötig? Weil es funktioniert ja auch ohne.
    Dankeschön schon mal im Voraus.



  • ohne kann es passieren das einfach die restlichen chars mitausgegeben werden...



  • Stromberg schrieb:

    Ist es bei C-Strings wichtig das Nullzeichen "\0" mit anzuhängen?

    Direkte Antwort: Ja.

    Ausführliche Antwort:
    Wenn Du einen Array wie unten angegeben initialisierst, hängt der Compiler automatisch ein Nullzeichen mit an (genauergesagt: Default-Konstruiert alle chars von 11 bis 59).
    Wenn Du C-Funktionen wie strcpy benutzt, hängt diese das Nullzeichen mit an. Das widerspricht nicht der Aussage "Ich hab jetzt schon in mehreren Büchern gelesen das man an das Ende eines C-Strings immer ein Nullzeichen anhängt". Denn irgendwer hängt ein Nullbyte an das Ende, nur eben nicht Du persönlich, sondern die Bibliotheksfunktion.

    download123 schrieb:

    ohne kann es passieren das einfach die restlichen chars mitausgegeben werden...

    Es kann nicht nur, es wird, denn eine C-Funktion die einen C-String auswertet, wertet so lange aus, bis sie ein Nullbyte findet, und sei es durch Zufall in den hinter dem String liegenden Daten.



  • wenn du's mit 'nem string initialisierst ("Hallo Welt"), dann wird schon automatisch eine 0 mit drangehängt.
    🙂



  • LordJaxom schrieb:

    genauergesagt: Default-Konstruiert alle chars von 11 bis 59

    seit wann müssen chars 'konstruiert' werden?
    😕



  • pale dog schrieb:

    seit wann müssen chars 'konstruiert' werden?
    😕

    Entschuldige, bei PODs heisst es natürlich default-initialisiert. 🙄 Wäre es ein Array von Objekten wäre es konstruiert, und allgemeingültig darf man es bestimmt auch so nennen (anstelle von "im Falle eines PODs default-initialisiert, sonst default-konstruiert").



  • LordJaxom schrieb:

    pale dog schrieb:

    seit wann müssen chars 'konstruiert' werden?
    😕

    Entschuldige, bei PODs heisst es natürlich default-initialisiert. 🙄

    nein, ich muss mich entschuldigen.
    ich hab' übersehen dass hier das C++ forum ist, dachte wir sind hier im ANSI-C forum.
    🙂



  • Mh also in diesem Fall muss ich kein Nullzeichen anhängen:

    char n[60]="Hallo Welt\0";
    

    und in diesem Falle auch nicht:

    #include <cstring>
    ....
    char n[60];
    strcpy(n,"Hallo Welt");
    

    und hier auch nicht:

    char n[]="Hallo Welt";
    

    weil der Compiler ja so nett is und das für mich automatisch erledigt.
    Ähm blöde Frage in welchem Fall muss ich den selber dann explizit mal ein Nullzeichen anhängen?
    Dankeschön schon mal im Voraus.



  • Zum Beispiel wenn Du Daten aus einem Device / Socket / Datei / whatever liest, denn hier macht es niemand für Dich, da es sich um Binärdaten handeln könnte. Wenn Du den Inhalt als C-String interpretieren willst, musst Du selbst für den Abschluss sorgen. (Achtung, Pseudocode)

    char buffer[maxlength+1];
    int length = read(file, buffer, maxlength);
    buffer[length] = '\0';
    cout << buffer;
    

    Oder wenn Du eine eigene Implementierung von strcpy schreibst, dann musst Du dafür natürlich auch Sorge tragen, und sei es indem Du das Nullbyte des Ursprungsstrings mitkopierst.



  • Stromberg schrieb:

    Ähm blöde Frage in welchem Fall muss ich den selber dann explizit mal ein Nullzeichen anhängen?

    char n[60] = {'H','a','l','l','o','\0'};
    

    🙂



  • Und nächste Frage, bei folgendem Code ist es zwar wie ich vorhin gelernt habe nicht nötig ein Nullzeichen anzuhängen, aber anhängen kann man doch trotzdem eins wenn man lustig ist oder?
    Aber irgendwie funktioniert das bei mir nicht.

    #include <iostream>
    using namespace std;
    
    int main()
    {
        char n[11]="Hallo Welt\0";
        return 0;
    }
    

    In "n" ist Platz für 11 Zeichen, "Hallo Welt" sind 10 Zeichen + das Nullzeichen "\0" = 11 Zeichen. Aber trotzdem funktionierts nicht? Also ist das hier anscheinden nicht zulässig oder? Der Compiler erkennt mein Nullzeichen nicht, und hängt nochmal sein eigenes mit dran oder?
    Dankeschön schon mal im Voraus.



  • Stromberg schrieb:

    Der Compiler erkennt mein Nullzeichen nicht, und hängt nochmal sein eigenes mit dran oder?

    richtig, du brauchst mindestens 12 zeichen...
    🙂



  • Jap, woher soll der Kompiler oder Präprozessor denn wissen was du vorhast?

    const char[] = "Hall\0o Wel\0t!\0";
    

    Woher soll er wissen welche Nullen das Ende markieren und welche einfach nur so da sind? Deshalb hängt er an String-Literale ("...") immer das Null-Zeichen an.

    Gruß
    Don06



  • Und noch n Problem, jetzt bin ich bei der Funktion "strncpy" angelangt, diese funktioniert ja so ähnlich wie strcpy, bloß das man ja bestimmen wie lang das rauszukopierende Wort sein soll.
    Folgender Code:

    #include <iostream>
    #include <cstring>
    using namespace std;
    
    int main()
    {
        char n[11];
        char l[]="Hallo Welt1234";
        strncpy(n,l,10);
        cout << n << endl;
        return 0;
    }
    

    AUSGABE:
    Hallo Weltù

    Was soll den bitte das "ù" da?
    Versteh ich nicht 😞
    Dankeschön schon mal im Voraus.



  • http://www.cplusplus.com/reference/clibrary/cstring/strncpy.html

    No null-character is implicitly appended to the end of destination, so destination will only be null-terminated if the length of the C string in source is less than num.



  • Ja also so ganz verstanden hab ichs noch nciht warum des passiert. Könntest du mir das vll. bisschen genauer erklären.
    Und anscheinend bin ich im Englischen auch nicht so gut, also ungefähr nach meinen Englischkentnissen hätte ich den Satz irgendwie so übersetzt.

    Kein Nullzeichen ist an das Ende vom Ziel angehängt worden, also wird das Ziel nur Null beendet sein wenn die Länge des C-Strings im Code kleiner als num ist.

    Aber was mir das jetzt eigentlich genau sagen soll weiß ich beim besten Willen nicht.
    Dankeschön schon mal im Voraus.



  • Es sagt nur, dass, wenn die Stringlänge kleiner als die Länge, die du bei num angegeben hast, ist, ein Terminierungszeichen angehängt wird. Ansonsten wird der String nicht nullterminiert!
    =>

    #include <iostream>
    #include <cstring>
    
    int main()
    {
        char n[11];
        char l[] = "Hallo Welt1234";
        strncpy(n, l, 10);
        n[10] = 0;
        std::cout << n << std::endl;
    }
    


  • Äh also muss ich bei strncpy einfach immer das Nullzeichen selbst mit anhängen oder? Das es mir der Compiler nicht automatisch mit anhängt?
    Dankeschön schon mal im Voraus.



  • Der Compiler soll da was machen? Hmm sollte normal die Funktion machen 😉
    Mach es einfach ...^^



  • Stromberg schrieb:

    Äh also muss ich bei strncpy einfach immer das Nullzeichen selbst mit anhängen oder? Das es mir der Compiler nicht automatisch mit anhängt?
    Dankeschön schon mal im Voraus.

    Das Problem ist das strncpy eine kaputte Funktion ist. Benutz sie einfach nicht. man: memcpy(3) ist dagegen wesentlich praktischer.

    (Zur Frage wann du eine \0 anhängen musst. Immer wenn du etwas wo keine \0 dran hängt als C-String benutzen willst. Ohne \0 am Ende ist es kein C-String)


Anmelden zum Antworten