stringstreams string to char number
-
"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
-
Nein, C ist manchmal schon okay. Man muss sich einfach bewusst sein, dass man sehr schnell auf Einschränkungen und Probleme trifft, die man mit den C++-Äquivalenten nicht hat. Hier wäre das die Fehlerbehandlung, andernorts sind es Pufferüberläufe, manuelle Speicherverwaltung und generelles Rumgefrickel.
Performance kann im Falle der Streams tatsächlich ein Grund für C sein, falls sie wirklich benötigt wird. Wenn es aber um Zeichenketten und Container geht, ist dieses Argument aber schnell einmal nicht mehr gegeben. Lustigerweise ist C++ in diesem Bereich sogar eher schneller

Und dann gibt es Dinge wie
<cmath>, gegen die hat keiner etwas. Man muss nicht gleich alles in eine Schublade stecken...
-
Wie gesagt - viele - nicht alle

Und ob jetzt niemand etwas gegen <cmath> hat kann ich nicht wirklich sagen
Kleine Anmerkung @berniebutt
Geschwindigkeit war für mich kein wirklicher Aspekt - ich versuche nur mich etwas weiter in C++ reinzudenken und dazu gehört nunmal auch die "C++-Variante" von atoi oder sonstwas zu kennen
-
cooky451 schrieb:
Kleine Anmerkung @berniebutt
Geschwindigkeit war für mich kein wirklicher Aspekt - ich versuche nur mich etwas weiter in C++ reinzudenken und dazu gehört nunmal auch die "C++-Variante" von atoi oder sonstwas zu kennen
Ist ok, kennen sollte man das schon. Gerade für kleine strings reichen die C-Methoden aber oft völlig aus, auch für deren Umwandlungen wie atoi oder itoa. Wer denkt da gleich an Performanceunterschiede? Aber - wie gesagt - es gibt viele C++ Puristen hier, für die reines C etwas unüblich gewordenes aus der Steinzeit ist. Diese Leute kennen auch nicht die Anfänge der PC-Programmierung, wo man oft notwendig OBJ-Files verschiedener Compiler wie FORTRAN, C, ASM, ... lustig miteinander gelinkt hatte.
Ich hoffe, du kannst deine Frage jetzt selbst beantworten! Es liegt mir fern, deinen Ehrgeiz zum Hinzulernen bremsen zu wollen. Was du dann wo und wie machst bleibt allein deine Sache!
Hauptsache es läuft sicher und stabil oder wenn nicht findest du schnell die Ursache und kannst sie mühelos bereinigen.
-
berniebutt schrieb:
Aber - wie gesagt - es gibt viele C++ Puristen hier, für die reines C etwas unüblich gewordenes aus der Steinzeit ist. Diese Leute kennen auch nicht die Anfänge der PC-Programmierung, wo man oft notwendig OBJ-Files verschiedener Compiler wie FORTRAN, C, ASM, ... lustig miteinander gelinkt hatte.
Das sind lediglich Geschichten die sich manche die C++ noch nicht ganz verstanden haben gern ausmalen

itoa() ist übrigens keine Standardfunktion.