Ich versuche zu konvertieren std::stringzu float/double. Ich habe es versucht:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Aber es gibt immer Null zurück. Irgendwelche anderen Möglichkeiten?
Ich versuche zu konvertieren std::stringzu float/double. Ich habe es versucht:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Aber es gibt immer Null zurück. Irgendwelche anderen Möglichkeiten?
Antworten:
std::string num = "0.6";
double temp = ::atof(num.c_str());
Für mich ist es eine gültige C ++ - Syntax, um einen String in ein Double zu konvertieren.
Sie können dies mit dem Stringstream oder boost :: lexical_cast tun, aber diese sind mit einer Leistungsbeeinträchtigung verbunden.
Ahaha du hast ein Qt Projekt ...
QString winOpacity("0.6");
double temp = winOpacity.toDouble();
Zusätzlicher Hinweis:
Wenn die Eingabedaten a sind const char*, QByteArray::toDoublesind sie schneller.
Die Standardbibliothek (C ++ 11) bietet die gewünschte Funktionalität mit std::stod:
std::string s = "0.6"
std::wstring ws = "0.7"
double d = std::stod(s);
double dw = std::stod(ws);
Im Allgemeinen für die meisten anderen Grundtypen siehe <string>. Es gibt auch einige neue Funktionen für C-Strings. Sehen<stdlib.h>
ostringstreaman sich war einfach zu lang, um zu tippen, geschweige denn zu verwenden ..
Lexikalische Besetzung ist sehr nett.
#include <boost/lexical_cast.hpp>
#include <iostream>
#include <string>
using std::endl;
using std::cout;
using std::string;
using boost::lexical_cast;
int main() {
string str = "0.6";
double dub = lexical_cast<double>(str);
cout << dub << endl;
}
try { ... boost::lexical_cast ... } catch (std::exception const& err) { //handle excpetion }
catch ( boost::bad_lexical_cast const& err ), um die Ausnahme abzufangen.
Sie können std :: stringstream verwenden:
#include <sstream>
#include <string>
template<typename T>
T StringToNumber(const std::string& numberAsString)
{
T valor;
std::stringstream stream(numberAsString);
stream >> valor;
if (stream.fail()) {
std::runtime_error e(numberAsString);
throw e;
}
return valor;
}
Verwendung:
double number= StringToNumber<double>("0.6");
Ja, mit einer lexikalischen Besetzung. Verwenden Sie einen Stringstream und den Operator << oder verwenden Sie Boost, sie haben ihn bereits implementiert.
Ihre eigene Version könnte folgendermaßen aussehen:
template<typename to, typename from>to lexical_cast(from const &x) {
std::stringstream os;
to ret;
os << x;
os >> ret;
return ret;
}
Sie können die lexikalische Besetzung verwenden:
#include <boost/lexical_cast.hpp>
string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;
Hinweis: boost :: lexical_cast löst eine Ausnahme aus, sodass Sie darauf vorbereitet sein sollten, damit umzugehen, wenn Sie einen ungültigen Wert übergeben. Versuchen Sie, eine Zeichenfolge ("xxx") zu übergeben.
Wenn Sie nicht den gesamten Boost ziehen möchten, gehen Sie zu strtod(3)from <cstdlib>- es wird bereits ein Double zurückgegeben.
#include <iostream>
#include <string>
#include <cstring>
#include <cstdlib>
using namespace std;
int main() {
std::string num = "0.6";
double temp = ::strtod(num.c_str(), 0);
cout << num << " " << temp << endl;
return 0;
}
Ausgänge:
$ g++ -o s s.cc
$ ./s
0.6 0.6
$
Warum funktioniert atof () nicht ... auf welcher Plattform / auf welchem Compiler bist du?
double myAtof ( string &num){
double tmp;
sscanf ( num.c_str(), "%lf" , &tmp);
return tmp;
}
Diese Antwort sichert litb in Ihren Kommentaren. Ich habe den tiefen Verdacht, dass Sie das Ergebnis einfach nicht richtig anzeigen.
Mir war genau das Gleiche einmal passiert. Ich habe einen ganzen Tag lang versucht herauszufinden, warum ich einen schlechten Wert in ein 64-Bit-Int bekommen habe, nur um herauszufinden, dass printf das zweite Byte ignoriert. Sie können nicht einfach einen 64-Bit-Wert an printf übergeben, wie es ein int ist.
Warum atof()funktioniert die ursprüngliche Frage nicht? Die Tatsache, dass sie doppelt besetzt ist, macht mich misstrauisch. Der Code sollte nicht ohne kompiliert werden #include <stdlib.h>, aber wenn die Umwandlung hinzugefügt wurde, um eine Kompilierungswarnung zu lösen, atof()wird sie nicht korrekt deklariert. Wenn der Compiler davon ausgeht, dass atof()ein int zurückgegeben wird, löst das Casting die Konvertierungswarnung, führt jedoch nicht dazu, dass der Rückgabewert als double erkannt wird.
#include <stdlib.h>
#include <string>
...
std::string num = "0.6";
double temp = atof(num.c_str());
sollte ohne Warnungen funktionieren.
Anstatt Boost in die Gleichung zu ziehen, können Sie Ihre Zeichenfolge (vorübergehend) als char[]und verwenden sprintf().
Aber wenn Sie Boost trotzdem verwenden, ist das natürlich kein allzu großes Problem.
Sie möchten Boost lexical_cast sowieso nicht für String <-> Gleitkomma. Diese Untergruppe von Anwendungsfällen ist die einzige Gruppe, für die Boost durchweg schlechter ist als die älteren Funktionen - und sie haben im Grunde alle ihre Fehler dort konzentriert, da ihre eigenen Leistungsergebnisse eine 20-25-fach langsamere Leistung zeigen als die Verwendung von sscanf und printf für solche Konvertierungen.
Google es selbst. boost :: lexical_cast kann etwa 50 Konvertierungen verarbeiten. Wenn Sie diejenigen mit Gleitkommazahlen ausschließen, ist dies genauso gut oder besser als die offensichtlichen Alternativen (mit dem zusätzlichen Vorteil, dass für alle diese Vorgänge eine einzige API vorhanden ist). Aber bringen Sie Schwimmer mit und es ist wie wenn die Titanic in Bezug auf die Leistung auf einen Eisberg trifft.
Die alten, dedizierten str-> double-Funktionen können alle 10000 Parses in etwa 30 ms (oder besser) durchführen. lexical_cast benötigt ungefähr 650 ms, um den gleichen Job zu erledigen.
Mein Problem:
Meine Lösung (verwendet die Windows-Funktion _wcstod_l):
// string to convert. Note: decimal seperator is ',' here
std::wstring str = L"1,101";
// Use this for error detection
wchar_t* stopString;
// Create a locale for "C". Thus a '.' is expected as decimal separator
double dbl = _wcstod_l(str.c_str(), &stopString, _create_locale(LC_ALL, "C"));
if (wcslen(stopString) != 0)
{
// ... error handling ... we'll run into this because of the separator
}
HTH ... ich habe ziemlich lange gebraucht, um zu dieser Lösung zu gelangen. Und ich habe immer noch das Gefühl, dass ich nicht genug über String-Lokalisierung und so weiß ...