string ist bei Ausgabe mit printf (null)


  • 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().



  • audacia schrieb:

    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().

    Ja, die Streams sind zum Teil etwas speziell. Allerdings habe ich die bisher nicht so kritisch betrachtet, was auch daran liegen könnte, dass ich kaum Alternativen kenne.

    Aber weshalb erachtest du die beiden Methoden als Designfehler? Weil sie durch andere Memberfunktionen eigentlich bereits abgedeckt sind (z.B. Dtor bei close() )?


  • Administrator

    audacia schrieb:

    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.

    1. Geschwindigkeit:
    http://www.cplusplus.com/reference/iostream/streambuf/pubsetbuf/
    Viele Implementationen haben standardmässig keinen Puffer gesetzt, weshalb sie als deutlich langsamer erscheinen. Der Puffer kann verdammt viel ausmachen.

    2. Moduslos:
    http://www.cplusplus.com/reference/iostream/ios/exceptions/
    Man kann sich über Modusänderungen sehr schnell und explizit informieren lassen.

    Grüssli


Anmelden zum Antworten