string ist bei Ausgabe mit printf (null)



  • Hallo!

    ich vermute mal äußerst simple Frage, aber warum ergibt folgender Code

    string hallo = "ichbineinstring";
    printf("%s",hallo);
    printf("\n");
    cout << hallo << endl;
    

    bei Nutzung von printf (null)?

    (null)
    ichbineinstring
    

    ?
    😕



  • Versuch mal die Methode c_str von std::string...


  • Administrator

    Weil es undefiniertes Verhalten ist.
    printf ist eine C Funktion und ist nur für fundamentale Typen gedacht. std::string dagegen ist eine Klasse, bzw. ein komplexer Typ.

    Es empfiehlt sich hier die C++ Funktionen für Ein- und Ausgabe zu verwenden:

    std::string hallo = "ichbineinstring";
    std::cout << hallo << std::endl;
    

    Grüssli



  • Nein, benutze in C++ std::cout für die Standardausgabe.

    printf() kommt aus C und kommt nur mit skalaren Typen zurecht. Ausserdem ist es durch die fehlende Typsicherheit recht fehleranfällig, wenn man nicht genau weiss, was man macht.



  • Ah, danke!

    string hallo = "ichbineinstring";
    char str[20] = "ichbinaucheinstring";
    printf("%s",str);
    printf("\n");
    cout << hallo << endl;
    getchar();
    

    So ist besser 🙂



  • PeterFragt schrieb:

    Ah, danke!

    string hallo = "ichbineinstring";
    char str[20] = "ichbinaucheinstring";
    printf("%s",str);
    printf("\n");
    cout << hallo << endl;
    getchar();
    

    So ist besser 🙂

    nicht wirklich...

    using namespace std;
    
    const char str[] = ".....";
    cout << str << endl;
    

    bb



  • Ja. Und da es normalerweise keinen Grund gibt, sich mit printf() rumzuschlagen, kannst du auch für char* den C++-Stream std::cout nehmen. Dieser funktioniert nämlich genauso und erkennt im Gegensatz zu printf() seinen Argumenttyp, du brauchst also kein "%s" .



  • Verstehe, danke!



  • Und falls du doch mal für irgendeine Funktion einen char* auf deinen std::string brauchst (soll schon mal vorkommen), dann nimm wie gesagt die Methode c_str, also "hallo.c_str()" (so würde es auch mit printf klappen)...



  • ich behalts im Hinterkopf



  • string z = "lutsch0r!";
    	printf( "%s", z.c_str());
    


  • PeterFragt schrieb:

    ich behalts im Hinterkopf

    aber behalts mit const char* und nicht char* im hinterkopf ^^
    braucht man aber eigtl nur für C-APIs

    bb



  • unskilled schrieb:

    braucht man aber eigtl nur für C-APIs

    Nö. Wie konstruierst du z.B. ein std::fstream-Objekt? 😉
    (In der Praxis benutzt man std::fstream natürlich nach Möglichkeit ohnehin nicht.)



  • audacia schrieb:

    ...

    hab ja extra "eigentlich" geschrieben - ist ja nicht so, dass ich nicht daran gedacht hätte 😉 danke ^^

    bb



  • Manchmal hat man ja auch mit C-APIs (oder C++-APIs, die trotzdem C-Strings verwenden) zu tun. Kann man sich nicht immer aussuchen, daher ist es auch gut, zu wissen was man in dem Fall mit seinen std::string's machen muss...



  • audacia schrieb:

    Nö. Wie konstruierst du z.B. ein std::fstream-Objekt? 😉

    Das sollte doch im kommenden Standard angepasst werden.

    audacia schrieb:

    (In der Praxis benutzt man std::fstream natürlich nach Möglichkeit ohnehin nicht.)

    Wie?



  • Nexus schrieb:

    audacia schrieb:

    (In der Praxis benutzt man std::fstream natürlich nach Möglichkeit ohnehin nicht.)

    Wie?

    Na du solltest natürlich fprintf/fscanf benutzen! Wusstest du das etwa nicht? 😉 😃



  • Nexus schrieb:

    audacia schrieb:

    (In der Praxis benutzt man std::fstream natürlich nach Möglichkeit ohnehin nicht.)

    Wie?

    Nun, die Streams sind in allen mir bekannten Implementationen langsamer als C-Streams (teilweise um Größenordnungen), und außerdem sind sie nicht moduslos, was Fehler in der Anwendung begünstigt und den korrekten Umgang massiv erschwert. Gewöhnlich ist man mit einem kleinen RAII-Wrapper um die C-Funktionen viel besser dran.



  • Okay, das kann gut sein, ich kenne die C-Funktionen aber auch zu wenig, um das genau beurteilen zu können.

    Naja, ich hatte bisher eigentlich nicht viele Probleme mit std::fstream , für meine Anwendungen reicht es. Ich finde zum Beispiel auch die Operatoren >> und << sehr komfortabel und habe momentan nicht wirklich Lust, alle Überladungen nachzuprogrammieren. 😉



  • Nexus schrieb:

    Okay, das kann gut sein, ich kenne die C-Funktionen aber auch zu wenig, um das genau beurteilen zu können.

    Man braucht die C-Funktionen nicht zu kennen, um zu sehen, daß es sich bei fstream um einen gewaltigen Designfehler handelt. Beispiele: die Existenz von fstream::good() und fstream::close().


Anmelden zum Antworten