Forum: PC-Programmierung C++: Umwandeln von String in Double


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Dennis S. (eltio)


Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,
welche Variante zur Konvertierung von String in Double ist in modernem 
C++ zu bevorzugen?
[....]
double value;

// Variante 1: String Stream
std::stringstream( "1234" ) >> value;

// Variante 2: Standard-Funktion
value = std::stod( "1234" );
[....]

Viele Grüße.

von Thomas R. (r3tr0)


Bewertung
0 lesenswert
nicht lesenswert
Nutze dazu eigentlich immer atof

double value;
string test = "test";

value = atof(test.c_str());

von Sven K. (quotschmacher)


Bewertung
0 lesenswert
nicht lesenswert
Thomas R. schrieb:
> value = atof(test.c_str());

das sieht mir stark nach c++ aus...


https://www.reddit.com/r/Cplusplus/comments/2m1cjo/is_there_any_benefit_associated_with_using/ 
da steht auch schon was dazu (also zur thread-frage, nicht zur nutzung 
von c-methoden)

von Dennis S. (eltio)


Bewertung
0 lesenswert
nicht lesenswert
Thomas R. schrieb:
> value = atof(test.c_str());
Das wäre eine weitere von vielen Varianten. Warum nutzt du diese? Ich 
persönlich habe "atof" und Varianten schon länger aus meinem Code 
verbannt.

Sven K. schrieb:
> das sieht mir stark nach c++ aus...
Das ist für C++ natürlich auch völlig in Ordnung! ;-) Der Link trifft 
das Thema glaube ich ganz gut, vielen Dank.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Dennis S. schrieb:
> Thomas R. schrieb:
>> value = atof(test.c_str());
> Das wäre eine weitere von vielen Varianten. Warum nutzt du diese? Ich
> persönlich habe "atof" und Varianten schon länger aus meinem Code
> verbannt.

atof() enthält keinerlei Möglichkeit zu erkennen, ob ein Fehler 
aufgetreten ist.  Wenn, dann sollte man strtod() verwenden. Aber warum 
dann nicht gleich std::stod(), das direkt mit einem std::string umgehen 
kann?

von MaWin (Gast)


Bewertung
0 lesenswert
nicht lesenswert
Dennis S. schrieb:
> welche Variante zur Konvertierung von String in Double ist in modernem
> C++ zu bevorzugen

Na, from_chars natürlich.

Ist so modern, das können die meisten Compiler noch nicht.

All diese Funktionen gehen aus strtod zurück, also besser die direkt 
verwenden. Das erspart wrpaaer die nichts anderes tun als Errorwerte 
umzuformatieren. Es sri denn, man will genau dss, eine exception statt 
einem error-code.

ABER: all diese Funktionen führen zu defekten Programmen.
value = std::stod( "12.4" );
geht kaputt, sobald dss Progrsmm nicht mehr in locale US läuft, sondern 
in locale DE. Weil dann ein , erwartrt wird. Also entweder vorher das 
locale setzen, oder diese Funktionen ganz meiden.

von Rolf M. (rmagnus)


Bewertung
1 lesenswert
nicht lesenswert
MaWin schrieb:
> ABER: all diese Funktionen führen zu defekten Programmen.value =
> std::stod( "12.4" );
> geht kaputt, sobald dss Progrsmm nicht mehr in locale US läuft, sondern
> in locale DE. Weil dann ein , erwartrt wird.

Das ist nicht "kaputt", sondern an die vom Benutzer eingestellte 
Landes-Konvention angepasst. Wenn man das nicht will:

> vorher das locale setzen

Immerhin kann man das da. Ich hatte letztens das umgekehrte Problem: Auf 
dem Rechner ist en_US als locale eingestellt gewesen, aber es sollten 
.csv-Files erstellt werden, die später von Excel eingelesen werden 
sollen. Leider funktioniert das in der deutschen Version von Excel nur, 
wenn in den .csv-Files ein Komma als Dezimaltrennzeichen verwendet wird. 
Der Import-Dialog bietet auch keine Möglichkeit, was anderes 
auszuwählen. Das würde ich dann tatsächlich als "kaputt" bezeichnen.

von Dennis S. (eltio)


Bewertung
0 lesenswert
nicht lesenswert
MaWin schrieb:
> Das erspart wrpaaer die nichts anderes tun als Errorwerte umzuformatieren.
Wenn man in C++ programmiert ist das in den meisten Fällen durchaus 
gewollt.

MaWin schrieb:
> Also entweder vorher das
> locale setzen, oder diese Funktionen ganz meiden.
Gilt das auch für die String Stream-Variante?

von Zeno (Gast)


Bewertung
0 lesenswert
nicht lesenswert
MaWin schrieb:
> All diese Funktionen gehen aus strtod zurück, also besser die direkt
> verwenden. Das erspart wrpaaer die nichts anderes tun als Errorwerte
> umzuformatieren. Es sri denn, man will genau dss, eine exception statt
> einem error-code.
>
> ABER: all diese Funktionen führen zu defekten Programmen.value =
> std::stod( "12.4" );
> geht kaputt, sobald dss Progrsmm nicht mehr in locale US läuft, sondern
> in locale DE. Weil dann ein , erwartrt wird. Also entweder vorher das
> locale setzen, oder diese Funktionen ganz meiden.

Deshalb habe ich mir für so etwas eine eigene Funktion geschrieben, die 
den Dezimaltrenner in der Defaulteinstellung ignoriert und das Komma in 
einen Punkt umwandelt. Die Umwandlung in die Zahl erfolgt dann mit einer 
Funktion die nicht mit den Lokalen arbeitet, sondern als Trenner den in 
der Programmierspache üblichen Dezimaltrenner Punkt benutzt.
Die Funktion kann auch mit den gelegentlich verwendeten 
Tausendertrennzeichen umgehen.

von Rolf M. (rmagnus)


Bewertung
0 lesenswert
nicht lesenswert
Zeno schrieb:
> Die Funktion kann auch mit den gelegentlich verwendeten Tausendertrennzeichen
> umgehen.

Das passt nicht so ganz zu dem:

> Deshalb habe ich mir für so etwas eine eigene Funktion geschrieben, die
> den Dezimaltrenner in der Defaulteinstellung ignoriert und das Komma in
> einen Punkt umwandelt.

Im Englischen wird das Komma als Tausender-Trennzeichen verwendet.

Aber warum überhaupt soviel Umstand, nur um nicht die locale setzen zu 
müssen?

von Yalu X. (yalu) (Moderator)


Bewertung
0 lesenswert
nicht lesenswert
Dennis S. schrieb:
> Gilt das auch für die String Stream-Variante?

Auch std:: stringstream richtet sich nach der eingestellten Locale.
Diese ist aber – unabhängig von den Benutzereinstellungen – beim
Programmstart immer "C", d.h. das Dezimaltrennzeichen ist der Punkt. Das
ändert sich erst, wenn du bspw. mit std::locale::global explizit etwas
anderes vorgibst.

Vorsicht ist geboten bei einigen GUI-Frameworks, die automatisch die
Benutzereinstellungen übernehmen.


Rolf M. schrieb:
> Aber warum überhaupt soviel Umstand, nur um nicht die locale setzen zu
> müssen?

Er möchte wahrscheinlich, dass sein Programm Eingaben sowohl in "C" als
auch in "de" verarbeiten kann (wobei das wegen der Tausendertrennzeichen
auch nicht zuverlässig funktionieren kann).

: Bearbeitet durch Moderator

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.