Sto cercando di convertire std::stringin float/double. Provai:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Ma restituisce sempre zero. Altri modi?
Sto cercando di convertire std::stringin float/double. Provai:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Ma restituisce sempre zero. Altri modi?
Risposte:
std::string num = "0.6";
double temp = ::atof(num.c_str());
Lo fa per me, è una sintassi C ++ valida per convertire una stringa in un double.
Puoi farlo con lo stringstream o boost :: lexical_cast ma quelli hanno una penalizzazione delle prestazioni.
Ahaha hai un progetto Qt ...
QString winOpacity("0.6");
double temp = winOpacity.toDouble();
Nota aggiuntiva:
se i dati di input sono a const char*, QByteArray::toDoublesarà più veloce.
La libreria standard (C ++ 11) offre le funzionalità desiderate con std::stod:
std::string s = "0.6"
std::wstring ws = "0.7"
double d = std::stod(s);
double dw = std::stod(ws);
Generalmente per la maggior parte degli altri tipi di base, vedere <string>. Ci sono anche alcune nuove funzionalità per le stringhe in C. Vedere<stdlib.h>
ostringstreamdi per sé era semplicemente troppo lungo per scrivere, figuriamoci usare ..
Il cast lessicale è molto carino.
#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 )per catturare l'eccezione.
Puoi usare std :: stringstream:
#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;
}
Utilizzo:
double number= StringToNumber<double>("0.6");
Sì, con un cast lessicale. Usa un flusso di stringhe e l'operatore << o usa Boost, lo hanno già implementato.
La tua versione potrebbe essere simile a:
template<typename to, typename from>to lexical_cast(from const &x) {
std::stringstream os;
to ret;
os << x;
os >> ret;
return ret;
}
Puoi usare il cast lessicale boost:
#include <boost/lexical_cast.hpp>
string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;
Nota: boost :: lexical_cast genera un'eccezione, quindi dovresti essere pronto a gestirla quando passi un valore non valido, prova a passare la stringa ("xxx")
Se non vuoi trascinare tutto il boost, vai con strtod(3)from <cstdlib>- restituisce già un doppio.
#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;
}
Uscite:
$ g++ -o s s.cc
$ ./s
0.6 0.6
$
Perché atof () non funziona ... su quale piattaforma / compilatore sei?
double myAtof ( string &num){
double tmp;
sscanf ( num.c_str(), "%lf" , &tmp);
return tmp;
}
Questa risposta sta tornando alla lettera nei tuoi commenti. Ho il profondo sospetto che tu non stia visualizzando correttamente il risultato.
Una volta mi è successa la stessa identica cosa. Ho passato un'intera giornata a cercare di capire perché stavo ottenendo un valore negativo in un int a 64 bit, solo per scoprire che printf ignorava il secondo byte. Non puoi semplicemente passare un valore a 64 bit a printf come se fosse un int.
Per quanto riguarda il motivo per cui atof()non funziona nella domanda originale: il fatto che sia stato scelto per il doppio mi rende sospettoso. Il codice non dovrebbe essere compilato senza #include <stdlib.h>, ma se il cast è stato aggiunto per risolvere un avviso di compilazione, atof()non viene dichiarato correttamente. Se il compilatore assume atof()restituisce un int, fusione che possa risolvere l'avviso di conversione, ma sarà non causa il valore di ritorno di essere riconosciuto come un doppio.
#include <stdlib.h>
#include <string>
...
std::string num = "0.6";
double temp = atof(num.c_str());
dovrebbe funzionare senza avvisi.
Invece di trascinare Boost nell'equazione, potresti mantenere la tua stringa (temporaneamente) come un file char[]e usaresprintf() .
Ma ovviamente se stai usando Boost comunque, non è davvero un grosso problema.
Non vuoi comunque Boost lexical_cast per string <-> floating point. Quel sottoinsieme di casi d'uso è l'unico insieme per il quale il potenziamento è costantemente peggiore delle funzioni precedenti e fondamentalmente hanno concentrato tutti i loro errori lì, perché i risultati delle loro prestazioni mostrano prestazioni 20-25 volte più lente rispetto all'utilizzo di sscanf e printf per tali conversioni.
Google da te. boost :: lexical_cast può gestire qualcosa come 50 conversioni e se escludi quelle che coinvolgono il floating point # è buono o migliore come le ovvie alternative (con l'ulteriore vantaggio di avere un'unica API per tutte quelle operazioni). Ma porta i galleggianti ed è come se il Titanic colpisse un iceberg in termini di prestazioni.
Le vecchie funzioni str-> double dedicate possono tutte eseguire 10000 analisi in qualcosa come 30 ms (o meglio). lexical_cast impiega qualcosa come 650 ms per fare lo stesso lavoro.
Il mio problema:
La mia soluzione (utilizza la funzione di Windows _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 ... mi ci è voluto parecchio tempo per arrivare a questa soluzione. E ho ancora la sensazione di non saperne abbastanza sulla localizzazione delle stringhe e cose del genere ...