String in Float konvertieren



  • Was man beachten sollte: Auch die C-Runtimes verwenden zu meiner Überraschung Sprach-
    Einstellungen. Das führte bei einem Programm von mir zu Problemen ohne Ende. Bin mir
    auch nicht ganz sicher, ob die Default-Einstellung die System-Einstellung oder Englisch
    (USA) ist.



  • die clib benutzt die alten clokals. standardeinstellung müsste eigentlich bs spezifisch sein.



  • hmm,

    fload b=atof(str.c_str());
    

    ist schneller geschrieben als:

    std::stringstream sstr;
    sstr<<str;
    float b;
    sstr>>b;
    

    Aber was man gebrauchen will...

    geht dass eigentlich auch?

    float b;
    static_cast<std::stringstream&>(std::stringstream()<<str)>>b;
    

  • Mod

    Green_Ghost schrieb:

    hmm,

    fload b=atof(str.c_str());
    

    ist schneller geschrieben als:

    std::stringstream sstr;
    sstr<<str;
    fload b;
    sstr>>b;
    

    Aber was man gebrauchen will...

    geht dass eigentlich auch?

    fload b;
    static_cast<std::stringstream&>(std::stringstream()<<str)>>b;
    

    das geht, eleganter ist aber

    float f;
    std::istringstream(s)>>f;
    


  • Am schönsten finde ich aber immer noch boost::lexical_cast. Einfach unschlagbar einfach und auch noch gut aussehend:

    string a;float b;
    b = lexical_cast<float>(a);
    a = lexical_cast<string>(b); //und zurück
    

    Sicherheit verbunden mit der Einfachheit von atof.

    ...anstatt jedesmal eine Exception reingeknallt zu kriegen.

    ich liebe exceptions. da weis man immer genau woran man ist. das ist toll 🙂 man kann nie falsche oder undefineirte werte benutzen wenn ne exception fliegt.

    Und genau deshalb mag ich die Stringstreams nicht!

    string a;float b;
    istringstream(a)>>b;
    

    Lässt es nähmlich nicht knallen sondern lässt b unverändert! Es müsste heißen

    string a;float b;
    istringstream in(a);
    in.exceptions(istringstream::failbit);
    in>>b;
    

    Und da exceptions kein istream& zurück gibt kann man es noch nicht einmal in eine Zeile quetschen. Dann kommt noch ein weiteres Problem hinzu : Bei der normalen Einstellung wirft istream keine Ausnahmen und es ist sehr leicht ein operator>> zu schreiben der darauf aufbaut. Nun wird die Einstellung gewechselt und istream::setstate wirft auf einmal. Das perfekte Scenario für einen schwer zu findenen Fehler.

    Dann gibt es noch ein weiteres Problem

    string a = "7,5";float b;
    istringstream(a)>>b;
    

    Hier wird lautlos einfach 5 in b geschrieben. Es muüsste heißen

    if((istringstream(a)>>b).peek() != EOF)
        cerr<<"error";
    

    boost::lexical_cast lässt es allerdings immer knallen wenn die Verwandlung fehlschlägt selbst wenn nicht der ganze string gelesen wurde und nutzt dabei noch nicht mal die in die Streams eingebauten Ausnahmen. Einfach herrlich. 🙂



  • Wieso geht denn das,

    if(static_cast<std::stringstream&>(std::stringstream()<<i).str().find('7')!=std::string::npos)
    

    aber das nicht?

    static_cast<std::ostringstream&>(std::ostringstream()<<str)>>b;
    

    Das wuerde ja heissen, dass ostringstream kein << op beim erstellen des streams erlaubt.

    Zweite frage...
    Wieso eigentlich

    static_cast<std::stringstream&>
    //und nicht
    static_cast<std::stringstream>
    //??
    

    Ghost



  • Green_Ghost schrieb:

    Wieso geht denn das,

    static_cast<std::ostringstream&>(std::ostringstream()<<str)>>b;
    

    Das wuerde ja heissen, dass ostringstream kein << op beim erstellen des streams erlaubt.

    Ne das geht nicht weil der ostringstream kein >> hat. Sollte er auch nicht. Damit das geht musst du ein stringstream benutzen.

    Green_Ghost schrieb:

    Zweite frage...
    Wieso eigentlich

    static_cast<std::stringstream&>
    //und nicht
    static_cast<std::stringstream>
    //??
    

    Ghost

    Weil std::stringstream nicht kopierbar ist.



  • @Ben04: das mit

    std::string a; float b;
    std::istringstream(a)>>b;
    

    hat bei mir geklapt.

    dafuer habe ich das mit dem cast nicht hinbekommen.
    Wobei man Cast ja auch nur wenn's sein muss einsetzen sollte.

    Ghost



  • Green_Ghost schrieb:

    @Ben04: das mit

    std::string a; float b;
    std::istringstream(a)>>b;
    

    hat bei mir geklapt.

    Hab ich gesagt, dass es nicht geht? Das Problem ist, dass es geht immer auch wenn es gar nicht gehen kann! Notfals bleibt b einfach lautlos unverändert oder wir schneiden einfach lautlos das ab was uns an a stört. "7,5" ist ja beinahe "7" also schreiben wir mal 7 in b.

    Green_Ghost schrieb:

    dafuer habe ich das mit dem cast nicht hinbekommen.
    Wobei man Cast ja auch nur wenn's sein muss einsetzen sollte.

    Meine Kristalkugel ist gerade in Reparatur. Du musst mir ausnahmsweise selbst sagen was für Probleme du hast.



  • static_cast<std::stringstream&>(std::stringstream()<<str)>>b;
    


  • Ben04 schrieb:

    Am schönsten finde ich aber immer noch boost::lexical_cast. Einfach unschlagbar einfach und auch noch gut aussehend:

    string a;float b;
    b = lexical_cast<float>(a);
    a = lexical_cast<string>(b); //und zurück
    

    Sicherheit verbunden mit der Einfachheit von atof.

    jo, stringstreams in action sind was feines. 😉

    Und da exceptions kein istream& zurück gibt kann man es noch nicht einmal in eine Zeile quetschen.

    das ist auch richtig so. übersichtlichkeit > kürze. die einze zeile bringt einen nicht um.

    niemand hat gesagt, dass die verwendung von stringstreams einfach ist, aber das sie der beste lösungsweg sind zeigt lexical_cast sehr schön(in dem sinne: danke für das Beispiel).



  • Wie sieht es denn bei lexical_cast mit der Sprachkonfiguration aus? Also ob deutsches
    oder englisches Format? Ob das umstellbar ist, etc...?



  • du musst das globale locale umstellen, das geht mit std::locale::global(deinLocale).

    dann benutzen alle streams, solange du ihnen kein anderes zugewiesen hast, diesen locale


Anmelden zum Antworten