FAQ - Umwandlung nach std::string und zurück
-
Das war genau mein Vorschlag bezüglich des Inhalts @ Nexus

-
no_comment schrieb:
person(std::string name, unsigned alter)
: name(name)
, alter(alter)
{}*stirnklatsch*
So benennt ein selbsternannter Profi-C++ler also seine member und parameter.Und was gibts daran auszusetzen? Weiters habe ich mich nirgens als C++ Profi bezeichnet.
-
Der Ansatz sieht schonmal recht brauchbar aus, allerdings läuft zumindest das Beispiel mit den selbstdefinierten IO-Operatoren über's Ziel hinaus. Selbst wenn du mit dem alten FAQ-Beitrag inhaltlich nicht zufrieden bist, könntest du zumindest die grundlegende Struktur übernehmen.
-
Ich schreib sonst mal einen Entwurf.
-
Hier wäre der Entwurf. Ich habe die Konvertierungen von und zu Strings jeweils zusammengefasst, damit die Ähnlichkeit deutlicher wird. Weiterführende Themen wie Fehlerbehandlung oder zusätzliche Parameter von
stoi()etc. habe ich der Einfachheit halber weggelassen. Ich wäre froh um Rückmeldungen und allfällige Verbesserungen.In C++ gibt es verschiedenste Möglichkeiten, Konvertierungen zwischen Zeichenketten (z.B.
std::string) und arithmetischen Typen (z.B.int,double) vorzunehmen. Im Folgenden sollen die wichtigsten davon erklärt werden.1. Standard-Konvertierungsfunktionen
Standardbibliotheken, die den C++11-Standard unterstützen, bieten diverse überladene Funktionen im Header
<string>an, welche eine direkte Umwandlung zwischen Strings und eingebauten Typen unterstützen. Die Konvertierung von arithmetischen Typen zu Strings erfolgt mit den folgenden überladenen Funktionen:to_string()zur Konvertierung instd::stringto_wstring()zur Konvertierung instd::wstring
In umgekehrter Richtung existieren folgende Funktionen, die jeweils für
std::string- undstd::wstring-Parameter überladen sind:stoi()fürintstol()fürlongstoll()fürlong longstoul()fürunsigned longstoull()fürunsigned long longstof()fürfloatstod()fürdoublestold()fürlong double
Die Anwendung sieht folgendermassen aus:
#include <string> int main() { // Zahl nach String double a = 4.72; std::string x = std::to_string(a); // String nach Zahl std::string y = "5.67"; double b = std::stod(y); }2. Stringstreams
Eine weitere Möglichkeit zur Umwandlung bietet die Klasse
std::stringstream. Falls nur Konvertierungen in eine Richtung erforderlich sind, kannstd::ostringstreamfür Output- undstd::istringstreamfür Input-Streams verwendet werden. Für Wide-Strings (std::wstring) existieren entsprechende Klassen mit vorangestelltem "w", z.B.std::wostringstream.Streams zahlen sich gegenüber den direkten Umwandlungsfunktionen vor allem dann aus, wenn mehrere Werte verkettet werden oder spezielle Stream-Funktionalität (wie Formatflags) erforderlich ist. Die Handhabung ist ähnlich zu
std::coutundstd::cin, zum Setzen und Auslesen des Strings können die überladenen Methodenstr()verwendet werden.#include <sstream> #include <string> int main() { double a = 4.72; int b = 88; // Output-Stream: Zahlen zu String zusammenfügen std::ostringstream oss; oss << a << ' ' << b; std::string x = oss.str(); // Input-Stream: Zahlen aus String extrahieren std::istringstream iss; iss.str("5.67 12"); // oder direkt Konstruktor verwenden iss >> a >> b; }3. Boost.LexicalCast
Boost ist eine Sammlung von C++-Bibliotheken und enthält unter anderem Funktionalität zur Umwandlung zwischen arithmetischen Datentypen und Zeichenketten. Dazu dient das Funktionstemplate
boost::lexical_cast<T>, wobeiTden Zieltypen der Konvertierung bezeichnet. Die Syntax ist analog zu den C++-Cast-Operatoren wie z.B.static_cast<T>.Gegenüber der ersten Variante besteht hier der Vorteil, dass keine C++11-Unterstützung notwendig ist. Im Weiteren ist die Syntax für alle Umwandlungen einheitlich, was generische Programmierung vereinfacht.
#include <boost/lexical_cast.hpp> #include <string> int main() { // Zahl nach String double a = 4.72; std::string x = boost::lexical_cast<std::string>(a); // String nach Zahl std::string y = "5.67"; double b = boost::lexical_cast<double>(y); }
-
Finde ich gut, allerdings sollte zumindest bei boost::lexical_cast auf die Fehlerbehandlung kurz eingegangen werden und bei Streams auf die Referenz verwiesen werden, meiner Meinung nach.
-
314159265358979 schrieb:
Finde ich gut, allerdings sollte zumindest bei boost::lexical_cast auf die Fehlerbehandlung kurz eingegangen werden und bei Streams auf die Referenz verwiesen werden, meiner Meinung nach.
Ich schlage vor, Du kopierst und änderst (machst debei die Änderungen kenntlich). Der nächste kopiert und ändert weiter. Und wenn alle Protagonisten damit zufrieden sind, wird's wohl so gut sein, daß es (unter Streichung aller Änderungsvermerke) in die FAQ gehört.
-
Meinst du das erst oder zynisch?

-
Dann kann man auch gleich ein Mercurial-Repository aufsetzen.

-
314159265358979 schrieb:
Meinst du das erst oder zynisch?

Ich glaube an das Gute.
Ich glaube daran, daß der Artikel schon fast fertig ist und binnen Tagen gegen eine nahezu perfekte Fassung konvergieren wird.
-
volkard schrieb:
Ich glaube daran, daß der Artikel schon fast fertig ist und binnen Tagen gegen eine nahezu perfekte Fassung konvergieren wird.
ist der Konvergenzradius denn groß genug? Und ist sicher, dass der Prozess eine ständig steigende Nutzenfunktion zu Folge hat? Gibt es vielleicht mehrere gute Lösungen mit suboptimalen Transienten dazwischen?
-
Finde Nexus Vorschlag schon richtig gut. Ich hab mal versucht, den Text ein bisschen kompakter zu schreiben. Der Code ist identisch außer den öffnenden geschweiften Klammern um jeweils eine Zeile zu sparen.
Hier einige Möglichkeiten, von
int,doubleusw instd::string(bzw.std::wstring) und umgekehrt zu konvertieren.1. Standard-Konvertierungsfunktionen (nur C++0x, ab GCC 4.?.? oder Visual Studio 2010)
Im neuen Standard gibt es im Header
<string>die Funktionento_string()undto_wstring()zur Konvertierung von nachstd::stringbzw.std::wstring.
Daneben fürstd::wstringundstd::wstringzu den arithmetischen Typen:stoi()fürintstol()fürlongstoll()fürlong longstoul()fürunsigned longstoull()fürunsigned long longstof()fürfloatstod()fürdoublestold()fürlong double
Anwendung:
#include <string> int main() { // Zahl nach String double a = 4.72; std::string x = std::to_string(a); // String nach Zahl std::string y = "5.67"; double b = std::stod(y); }2. Stringstreams
Wer C++x0 nicht nutzt, kann
std::stringstreamnehmen. Falls nur Konvertierungen in eine Richtung erforderlich sind, kannstd::ostringstreamfür Output- undstd::istringstreamfür Input-Streams verwendet werden. Für Wide-Strings (std::wstring) analog mit vorangestelltem "w", z.B.std::wostringstream.
Hier lassen sich auch leicht mehrere Werte verkettet werden oder z.B. Formatflags einsetzen. Die Handhabung ist ähnlich zustd::coutundstd::cin. Zum Setzen und Auslesen des Strings können die überladenen Methodenstr()verwendet werden.#include <sstream> #include <string> int main() { double a = 4.72; int b = 88; // Output-Stream: Zahlen zu String zusammenfügen std::ostringstream oss; oss << a << ' ' << b; std::string x = oss.str(); // Input-Stream: Zahlen aus String extrahieren std::istringstream iss; iss.str("5.67 12"); // oder direkt Konstruktor verwenden iss >> a >> b; }3. Boost.LexicalCast
Boost ist eine beliebte Sammlung von C++-Bibliotheken und enthält unter anderem das Funktionstemplate
boost::lexical_cast<T>mitTals Zieltyp der Konvertierung. Die Syntax ist analog zu den C++-Cast-Operatoren wie z.B.static_cast<T>. Die einheitliche Syntax für Umwandlungen vereinfacht generische Programmierung.#include <boost/lexical_cast.hpp> #include <string> int main() { // Zahl nach String double a = 4.72; std::string x = boost::lexical_cast<std::string>(a); // String nach Zahl std::string y = "5.67"; double b = boost::lexical_cast<double>(y); }
-
Crap, doch noch ein paar Schnitzer drin.
Die letzten zwei Sätze
Die Syntax ist analog zu den C++-Cast-Operatoren wie z.B. static_cast<T> und gut geeignet für generische Programmierung.
-
Nur am Rande: Sollte nicht auch zumindest die Rolle der locale erwähnt werden, weil hier auch doubles/Floats vorkommen.
Bei ints spielt es ja keine Rolle.Just my 2 cents...
-
Allzu kurz finde ich nicht gut, ich würde schon die Vorteile der einzelnen Varianten als solche hervorheben, damit gleich klar wird, wann welche Möglichkeit zu verwenden ist. So lange sind die Beschreibungen in meinem Post nun auch wieder nicht

Und was den Code anbelangt: Öffnende und schliessende Klammern auf der gleichen Höhe finde ich um einiges übersichtlicher. Ist ja nicht so, dass wir hier unbedingt die eine Zeile sparen müssten.
Bezüglich Locales: Wäre eine Möglichkeit. Dann würde ich aber auch auf Fehlerbehandlung eingehen. Ich habe solche Dinge wie erwähnt weggelassen, da der Artikel primär eine Übersicht über die verschiedenen Wege zur String-Konvertierung geben soll. Besonders Anfänger sind vielleicht froh, wenn sie gerade die wichtigen Daten auf einen Blick haben. Man könnte aber am Schluss eine Liste mit weiterführenden Links (z.B. über Streams) anfügen.