Frage zu C-String



  • raw** schrieb:

    Ein Nullbyte Kennzeichnet ja eigentlich auch das string ende ...

    Bei einem C-String wuerde (die C++-Version von) strlen so aussehen:

    template<charT> //Oder so aehnlich. Selbst geschrieben.
    size_t strlen(charT const* ptr)
    {
        size_t rval(0);
        while( ptr++ ) ++rval;
        return rval;
    }
    

    Es wird bis zum ersten Terminierungszeichen (0 oder als character-Literal: '\0') gelesen.
    wie aber sieht std::string::length() aus?

    template< //Oder so aehnlich. Selbst geschrieben.
        typename CharT, 
        typename Traits, 
        typename Allocator
    >
    typename basic_string<CharT, Traits, Allocator>::size_type basic_string::length() const
    {
        return mSize;//Oder so aehnlich
    }
    

    Hier wird ein interner, vorzeichenloser Skalar zurueckgegeben. Was heisst das? std::string speichert die Laenge mit! Und fuer den sind damit Terminierungszeichen irrelevant:

    std::string a(5, '\0'); // Ein String, der aus 5 Nullbytes besteht
    
    std::cout << a.length(); //5
    

    Wieso funktioniert dann folgendes nicht:

    std::string a = "\0\0\0\0\0";
    std::cout << a.length();
    

    Das in der ersten Zeile nennt sich copy-initialisation. Hier wird a der Wert "\0\0\0\0\0" zugewiesen; der entsprechende Konstruktor wird aufgerufen.

    Allerdings kennt dieser Konstruktor die Laenge des uebergebenen C-Strings nicht; er muss ihn also als Null-terminiert betrachten und hoert damit beim ersten Buchstaben auf. Die Laenge ist dementsprechend 0.

    Wie es trotzdem geht?

    char const[] meinScheiss = "\0\0\0\0\0";
    
    std::string a(meinScheiss, meinScheiss + sizeof MeinScheiss); //start-end Iteratorenpaar Konstruktor
    
    std::cout << a.length();
    

    Hier wird 6 herausgegeben. Wieso?
    Sehen wir uns an, was da steht:

    char const[] meinScheiss = "\0\0\0\0\0";
    

    Wird vom Compiler zu

    char const[6] meinScheiss = {'\0', '\0', '\0', '\0', '\0', '\0'};
    

    Geaendert. An die Fuenf Terminierungszeichen wird noch eines rangehaengt (macht der Compiler bei solchen Literalen automatisch).


Anmelden zum Antworten