Wie Convertiere ich einen String zu Integer
-
Stani96 schrieb:
Hallo zusammen,ich habe hier eine Variable erstellt (string height,width) ,die ich mit fstream aus einer Datei gelesen habe.Jetzt muss ich das in eine Integer umwandeln.Ich habe es schon mit atoi()... probiert ,geht aber iwie nicht
Hallo Stani96,
wenn Du strings aus einer Datei lesen kannst, so kannst Du auch int lesen .. einfach so:
#include <fstream> #include <iostream> int main() { using namespace std; ifstream file( "Datei.txt" ); int height, width; if( file >> height >> width ) // wieso string lesen, wenn amn auch int lesen kann { cout << "Gelesen: " << height << ", " << width << endl; } else cerr << "Lesefehler" << endl; return 0; }
:xmas2: Werner
-
Ich finde die FAQ hier schlecht. Der Artikel von der FAQ verweist auf eine stark verkürzte, dafür deutsche Übersetzung von http://www.gotw.ca/publications/mill19.htm (das geht in Ordnung, weil deutsch).
Schlimmer finde ich, dass der Beitrag völlig veraltet ist und (im Gegensatz zum Originalartikel) nicht aufboost::lexical_cast
eingeht, dafür aber aufstrstream
. Das ist zwar alles korrekt, weil nur Standard-C++-Möglichkeiten genannt werden wollen, aber ich wäre lieber auf zukunftsträchtige Möglichkeiten wie lexical_cast eingegangen, wie auf offiziell veraltete Möglichkeiten (strstream).Ein C++-Anfänger weiss nicht, nach welchen Kriterien auszuwählen, weil nur eine Auflistung vorgelegt wird. Im Zweifelsfall nimmt man halt die kürzeste von allen:
#include <stdio.h> // non-standard-c++ #include <stdlib.h> // non-standard-c++ int main() { double d = 3.14; char buffer[10]; sprintf(buffer, "%g", d); printf("%s\n", buffer); system("pause"); // ... }
In Standard-C++ hat man drei verschiedene Möglichkeiten um eine Zahl
in einen String umzuwandeln.
Eine genaue Beschreibung der verschiedenen Möglichkeiten samt ihrer Vor- und
Nachteile findet man hier.Den Grammatikfehler habe ich markiert, mich frappiert aber besonders stark die eben gezeigte Möglichkeit.
Überdies gefallen mir die anderen kurzen Codes nicht, weil der std-namespace unverzüglich geöffnet wird und komische Variablennamen gewählt wurden (string ZahlAlsString(Str.str());
Zeile 10 bzw. 11). Dass der Buffer eine feste Grösse hat, scheint nicht zu stören.Bezüglich Form bin ich noch nicht fertig:
Wie wandelt man eigentlich eine Zahl in einen String?
Dass das ein unvollständiger Satz ist fällt scheinbar niemandem auf, zudem kommt im übernächsten Satz kommt das Wort "eigentlich" schon wieder vor.
In Kürze:
---------Das gezeigte Formatierungsproblem sowie die nervigen und vor allem unregelmässigen Zeilenumbrüche sollten ebenfalls beseitigt werden.
Die prinzipiell wichtige Frage, woher denn der string stammt wird ignoriert, meistens (
std::cin
oder eigene Instanz vonstd::file
bzw. allgemeiner vonstd::istream
) löst sich das Problem von alleine (siehe Werni).Weil der Artikel von 2002 stammt, ist das alles verzeihbar, die letzte Revision vom 08.2009 hat aber scheinbar nicht ausgereicht, alle Fehler zu eliminieren. Ich meine, das sollte jetzt nachgeholt werden.
:xmas2: :xmas1: :xmas2:
-
badfaq schrieb:
Wie wandelt man eigentlich eine Zahl in einen String?
Dass das ein unvollständiger Satz ist fällt scheinbar niemandem auf, zudem (...)
Was ist denn daran unvollständig? Bzw. wie würde er vollständig aussehen?
Geht dir das "um" am Ende ab? Dann lass dir sagen dass "wandeln" ein (vollständiges) deutsches Verb ist.Duden schrieb:
wandeln 1. [ab]ändern, anders werden lassen, umändern, umbilden, umformen, variieren, verwandeln; (bildungsspr.): modifizieren; (ugs.) ...
ps: ich finde "wandeln" in diesem Satz auch nicht gut, ich hätte auch eher umwandeln geschrieben oder verwandeln oder konvertieren. Aber korrekt ist es denke ich schon.
-
hustbaer schrieb:
wie würde er vollständig aussehen?
Ich meinte schon das "um".
Intuitiv hätte ich gesagt, es heisst "wandeln zu" und nicht "wandeln in", wenn es das Gleiche wie "umändern" bedeuten soll, aber dafür finde ich keine Belege.
Einigen wir uns also darauf, dass es mit "umwandeln" besser getan ist.Viel schlimmer als das Deutsch finde ich den gezeigten Code (C-Header, bufferoverflowgefährdet,
system("pause")
, usw.) und den ungezeigten Code (ebenfalls bufferoverflowgefährdet,using namespace std
, Variablenbenennung, deprecated, usw.).
-
badfaq schrieb:
Ich finde die FAQ hier schlecht.
Kein Problem.
Erstelle einen Post mit einem besseren Eintrag und melde das einem Moderator.
-
Shade Of Mine schrieb:
Erstelle einen Post mit einem besseren Eintrag und melde das einem Moderator.
Ich hab jetzt Zeit gefunden und das getan. Bitte schaut, ob darin etwas fehlt, Schreibfehler enthalten sind oder sonstige Beanstandungen gemacht werden können. Wenn alles überprüft ist, dann poste ich ihn unter einem neuen Thread.
Weil sich badfaq nicht so richtig macht, nehme ich für den FAQ Eintrag meinen Vornamen.
-
Folgende Fragen werden hier in allen Variationen beantwortet:
- Wie wandle ich eine Zahl in einen String um?
- Wie wandle ich einen String in eine Zahl um?
1 Die kurze Lösung
Der Rechner merkt sich eine Zahl üblicherweise nicht als Zeichenkette, sondern als eine Folge von Bits. Um sie dennoch untereinander zu konvertieren, bietet C++ den
std::ostringstream
bzw.std::istringstream
an.- Zahl zu String
double d = 1.618; std::ostringstream os; os << d; std::string str(os.str());
- String zu Zahl
std::string str("1.618"); std::istringstream is(str); double d; is >> d;
Für die Beispiele benötigt man die Header
<string>
und<sstream>
.
Das Schöne an der Sache ist, dass sich das Gezeigte für alle Typen verallgemeinern lässt, fürint
s,float
s und eigenen Klassen gleichermassen – es geht überall gleich.Ein vollständiges Programm sieht so aus:
#include <iostream> #include <sstream> #include <string> std::string int_to_string(int i) { std::ostringstream os; os << i; return os.str(); } int string_to_int(const std::string& str) { std::istringstream is(str); int i; is >> i; return i; } int main() { // Der ganze Teil hier ist ab unsinnig, bitte // auf keinen Fall etwas derartiges übernehmen. std::string s; std::cout << "Gib eine Zahl ein: "; std::cin >> s; int number = string_to_int(s); std::string square = int_to_string(number*number); std::cout << "Das Quadrat davon: " << square << std::endl; }
2 Die Sinnfrage
Die Daten muss man von irgendwo her haben und meistens ist das über die Standard Ein- bzw. Ausgabe oder eine Datei. Wenn dies über ein Stream-Objekt abläuft, dann benötigt man keinen zusätzlichen
std::stringstream
, weil die Funktionalität schon durch alle vonstd::ostream
und/oderstd::istream
abgeleiteten Klassen bereitgestellt wird.
Obiges Beispiel in der normalen Implementation:#include <iostream> int main() { std::cout << "Gib eine Zahl ein: "; int nr; std::cin >> nr; std::cout << "Das Quadrat davon: " << nr*nr << std::endl; }
Gleiches ist analog dazu mit
std::file
u.ä. möglich.3 Boost
Wer sich fragt, ob es denn nicht eine simple Funktion gebe, die das einfach und schnell erledigt (wie
itoa
/atoi
in C), der wird enttäuscht sein: das gibt es nicht.
Jedenfalls solange wie wir uns aufs Standard C++ beschränken. Alle grossen GUI-Bibliotheken beinhalten eine solche Funktion, sollte das Problem bei deiner grafischen Oberfläche auftreten, schau noch einmal in ihrer Dokumentation nach (es gibt dafür auch zugeschnittene Steuerelemente).
Boost istdie
Bibliothek für fortgeschrittene C++-Programmierer und wird in vielen Projekten so oder so gebraucht. Wenn das der Fall ist, spricht nichts gegen die Verwendung vonboost::lexical_cast<>()
:unsigned short age = lexical_cast<unsigned short>("17"); std::string age_str = lexical_cast< std::string >(age );
4 Alle Standard C++-Möglichkeiten
-
Zahl zu String
-
std::ostream
(aus<sstream>
; empfohlen, aber etwas langsam)
double d = 1.618; std::ostringstream os; os << d; std::string str(os.str());
std::ostrstream
(aus<strstream>
; deprecapted/veraltet. Wird in zukünftigen C++-Versionen nicht mehr unterstützt. Anfällig auf Bufferoverflows)
double d = 1.618; char buf[6]; std::ostrstringstream os(buf); os << d << std::ends; std::string str(os.str());
sprintf
(aus<cstdio>
; Relikt aus C, fühlt sich in C++ fremd an. Anfällig auf Bufferoverflows)
double d = 1.618; char buf[10]; sprintf(buf, "%g", d); std::string str(buf);
- String zu Zahl
std::istringstream
(aus<sstream>
; empfohlen)
std::string str("1.618"); std::istringstream is(str); double d; is >> d;
std::istrstream
(aus<strstream>
; auf diese Weise absolut unnötig, aber rein theoretisch möglich)
std::string str("1.618"); std::istrstream is(str.c_str()); double d; is >> d;
sscanf
(aus<cstdio>
; Relikt aus C, fühlt sich in C++ fremd an. So herum risikofrei)
std::string str("1.618"); double d; sscanf(str.c_str(), "%lf", &d);
atof
/atoi
/atol
bzw.strtod
/strtol
/strtoul
(aus<cstdlib>
; schnelle C-typische Umwandlungsfunktion. Keine Überladungen. Die str*-Funktionen bieten mehr Optionen an, die hier nicht gebraucht werden)
std::string str("1.618"); double d = atof(str.c_str());
5 Vergleich
Herb Sutter hat die Konvertierung Zahl zu String im Artikel The String Formatters of Manor Farm (Nov. 2001) untersucht, der die C++-Möglichkeiten mit
boost::lexical_cast<>
auf ihre Vor- und Nachteile, besonders in ihrer Geschwindigkeit vergleicht. Eine deutsche Übersetzung, die den Artikel stark verkürzt wiedergibt, findet sich hier.Wer auf ein wirklich gutes Laufzeitverhalten angewiesen ist, für den sind diese beiden englischsprachigen Artikel (Feb. 2010) interessant:
Die Überraschung ist, dass Boost.Spirit.Karma als eindeutiger Sieger von String zu Int feststeht, umgekehrt ist es eine "naive" Eigenimplementation.
-
Alert the moderator by using a special user name.
-
Ich weiß nicht recht. Vielen Dank für die Mühe, aber es beinhaltet zahlreiche Ungenauigkeiten oder schlicht und einfach Fehler. Da es aber eine gute Basis darstellt, werde ich es wenn ich mal etwas Zeit habe (heute bestimmt nicht mehr), überarbeiten und eintragen. Mit deiner Erlaubnis natürlich, dass ich an deinem Text noch Korrekturen vornehmen darf.
-
Erlaubnis erteilt.
-
... sofern die Änderungen nicht ausschliesslich den Sinn haben, SeppJ als Autor angeben zu können.
-
j0hannes schrieb:
... sofern die Änderungen nicht ausschliesslich den Sinn haben, SeppJ als Autor angeben zu können.
Nee, da stünde dann bloß ein "zuletzt berabeitet von" unten dran. Aber wie gesagt nicht heute. Und ich würde dir den überarbeiteten Eintrag natürlich vorher nochmal zeigen und erklären was ich warum geändert habe.