stringstreams string to char number
-
Guten,
ich würde gerne via stringstreams aus einem string eine Zahl machen - diese allerdings in einem char speichern.
Also aus
const char foo[] = "132";soll
char bar = 132;werden.
Geht das? Und wenn ja wie mache ich das?
-
Dazu gabs doch schon zig threads.
Um diese zu finden darf man auch gern mal die Suchfunktion des Forums nutzen.
Ausserdem findet sich ein Beitrag unter den FAQs Einmal Zahl nach String und zurück
-
Top..
schonmalconst char foo[] = "123"; char bar; std::stringstream ss; ss << foo; ss >> bar; std::cout << bar << std::endl;versucht? Tipp: Ausgabe ist "1" und leider nicht "123" oder irgendein komisches Zeichen mit dem Wert 123.
-
Du packst "123" in den stringstream.
Und dann liest du wieder in ein char aus.Nun die Frage: Was erwartet man normalerweise als Resultat? '1' oder 123?
-
"Normalerweise" interessiert mich gerade aber reichlich wenig. Was mich schon mehr interessiert steht oben

-
Eine einfache Möglicheit wäre der Umweg über ein int:
const char foo[] = "123"; int number; char bar = 0; std::stringstream ss; ss << foo; ss >> number; if (number > std::numeric_limits<char>::min() && number < std::numeric_limits<char>::max() ) bar = static_cast<char>(number); std::cout << bar << std::endl;
-
Ok, das hätte als Antwort doch schon gereicht. Ich schließe jetzt einfach mal daraus dass es keinen "Manipulator" wie "hex" oder sowas extra für diesen Zweck gibt - dann wird der Umweg über int wohl am besten sein.
Dann hätte ich da gleich noch eine kleine Frage hinterher - und zwar ob der C++ Standard folgenden Ausdruck garantiert.
using namespace std; stringstream ss; char foo[] = "68719476736"; long long bar; ss << foo; ss >> bar;Denn mit meinem Compiler (VS 2010) klappt das zwar ohne Probleme, allerdings wird hier ( http://www.cplusplus.com/reference/iostream/ostream/operator<</ ) nichts für "long long" angezeigt.
-
Auf vielen Systemen sollte dies gehen:
ss >> (*reinterpret_cast<int*>(&bar));Der reinterpret_cast macht einen aber schon zurecht darauf aufmerksam, dass hier gepfuscht wird. Ich würde den Umweg über den int wählen.
-
SeppJ schrieb:
Auf vielen Systemen sollte dies gehen:
ss >> (*reinterpret_cast<int*>(&bar));Der reinterpret_cast macht einen aber schon zurecht darauf aufmerksam, dass hier gepfuscht wird. Ich würde den Umweg über den int wählen.
Das sollte aber nur auf System mit Little Endian funktionieren oder? Ansonsten schreibt er ja in &bar+3 - was eher ungünstig wäre.
-
inter2k3 schrieb:
Das sollte aber nur auf System mit Little Endian funktionieren oder? Ansonsten schreibt er ja in &bar+3 - was eher ungünstig wäre.
Genau. Deswegen auch nur viele und nicht alle. Und wie gesagt, ich würde es auch nicht so machen. Aber ich wollte es nicht als Alternative vorenthalten.
-
Frage: Was kann man denn über die Herkunft des Strings
foosagen? D.h. kann man mit Sicherheit sagen, dass der Wertebereich auch garantiert in eincharpasst?Ansonsten ist der Umweg über einen größeren Typ wie
intauf jeden Fall besser, da nur so eine Bereichsüberschreitung festgestellt und ein entsprechender Fehlercode oder eine Exception erzeugt werden kann.Bei inter2k3s Lösung enthält
barim Fehlerfall eine 0 - die als korrekt angesehen werden könnte.
-
Hier würde ich ganz klar atoi() verwenden.
Deutlich mehr Performance bei einfacherer Anwendung.char numberString[] = "123";
char number = atoi(numberString);
-
Nur mal ne ganz dumme Frage: Warum muss es genau ein char sein?
-
Ethon schrieb:
Hier würde ich ganz klar atoi() verwenden.
Deutlich mehr Performance bei einfacherer Anwendung.Ich habe aber noch nie verstanden, wie man bei
atoi()sinnvoll Fehler abfragt. Wie macht man das?Übrigens:
boost::lexical_cast()sollte für eingebaute Datentypen auch recht gut optimiert sein. Das kann auch mitstd::stringumgehen...
-
Ich habe aber noch nie verstanden, wie man bei atoi() sinnvoll Fehler abfragt. Wie macht man das?
Die Fehlerbehandlung beschränkt sich bei atoi auf ein Checken nach 0 bzw INT_MAX / INT_MIN.
Naja, hängt vom Input ab. Wenn man weiß dass der Input möglicherweise fehlerhaft ist, würde ich auch boost::lexical_cast verwenden.
Stringstreams bringen halt ne Menge Overhead mit. Was mich dabei am meisten stört ist dass der String erstmal in den internen Buffer kopiert wird bzw der anglegt werden muss. Sollte eigentlich unproblematisch sein, eine Art stringstream zu bauen, der nicht buffert und nur einen Zeiger auf die Zeichenkette besitzt.
Geschätzt die Hälfte der Zeit ist bei meinem aktuellen Projekt die CPU beschäftigt zwischen Buffern hin- und herzukopieren bzw Speicher zu besorgen. Und das in 90% der Fälle grundlos, da meine Rohdaten sowieso die komplette Lebensdauer des stringstreams gültig sind bzw verändert werden dürfen ...
-
Wenn du mich fragst machst du was ganz grundlegend falsch wenn du ständig neue stringstreams erzeugen und wieder zerstören musst...
-
Naja, ich bekomme per Netzwerk permanent Strings rein, die geparsed werden müssen.
Heißt, als erstes buffert boost::asio sie zwischen, bevor sie in einem std::string wandern, der meinen Callbacks übergeben wird. Die Callbacks kopieren sie wiederrum in einen Stringstream um sie parsen zu können.Wenn ich sowohl den Code von Asio als auch von stringstream ändern könnte, würde einfach einen Vektor mit ausreichender Kapazität für die Strings reserviert werden, der direkt durch die entsprechende Input-Funktionen (hier wohl recv) befüllt werden würde und der stringstream würde das nicht auch nochmal kopieren.
-
Ethon schrieb:
Die Fehlerbehandlung beschränkt sich bei atoi auf ein Checken nach 0 bzw INT_MAX / INT_MIN.
Also keine Fehlerbehandlung. Das macht
atoi()nutzlos für alle Fälle, wo die Eingabe nicht garantiert im richtigen Format vorliegt. Unter anderem für alle Benutzereingaben...
-
Wieso gibt es hier immer wieder so simple Fragen, die mit der Standardlibrary stdlib von C ausreichend abgedeckt sind? Die Streamklassen von C++ dienen nur der unkomplizierten Ein- und Ausgabe.
Ich habe zunehmend Probleme, solche Fragen und die darauf gegebenen Antworten zu verstehen! 
-
Das Problem ist dass die C Standardlib für viele C++ler wohl tabu ist

Wenn man also nicht gleich ca. 100 flames kassieren möchte nutzt man in C++ Projekten am besten auch nur C++. Ob das jetzt gut oder schlecht ist dazu äußere ich mich mal nicht