Je suis en train de convertir std::stringà float/double. J'ai essayé:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Mais il renvoie toujours zéro. D'autres moyens?
Je suis en train de convertir std::stringà float/double. J'ai essayé:
std::string num = "0.6";
double temp = (double)atof(num.c_str());
Mais il renvoie toujours zéro. D'autres moyens?
Réponses:
std::string num = "0.6";
double temp = ::atof(num.c_str());
Le fait-il pour moi, c'est une syntaxe C ++ valide pour convertir une chaîne en double.
Vous pouvez le faire avec le stringstream ou boost :: lexical_cast mais ceux-ci viennent avec une pénalité de performance.
Ahaha vous avez un projet Qt ...
QString winOpacity("0.6");
double temp = winOpacity.toDouble();
Remarque supplémentaire:
si les données d'entrée sont a const char*, ce QByteArray::toDoublesera plus rapide.
La bibliothèque standard (C ++ 11) offre la fonctionnalité souhaitée avec std::stod:
std::string s = "0.6"
std::wstring ws = "0.7"
double d = std::stod(s);
double dw = std::stod(ws);
Généralement pour la plupart des autres types de base, voir <string> . Il existe également de nouvelles fonctionnalités pour les chaînes C. Voir<stdlib.h>
ostringstreamen soi était tout simplement trop long à taper, et encore moins à utiliser ..
Le casting lexical est très agréable.
#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 )pour attraper l'exception.
Vous pouvez utiliser 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;
}
Usage:
double number= StringToNumber<double>("0.6");
Oui, avec une distribution lexicale. Utilisez un stringstream et l'opérateur <<, ou utilisez Boost, ils l'ont déjà implémenté.
Votre propre version pourrait ressembler à:
template<typename to, typename from>to lexical_cast(from const &x) {
std::stringstream os;
to ret;
os << x;
os >> ret;
return ret;
}
Vous pouvez utiliser boost lexical cast:
#include <boost/lexical_cast.hpp>
string v("0.6");
double dd = boost::lexical_cast<double>(v);
cout << dd << endl;
Remarque: boost :: lexical_cast lève une exception, vous devez donc être prêt à y faire face lorsque vous passez une valeur non valide, essayez de passer une chaîne ("xxx")
Si vous ne voulez pas faire glisser tout le boost, utilisez strtod(3)from <cstdlib>- il renvoie déjà un double.
#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;
}
Les sorties:
$ g++ -o s s.cc
$ ./s
0.6 0.6
$
Pourquoi atof () ne fonctionne pas ... sur quelle plate-forme / compilateur êtes-vous?
double myAtof ( string &num){
double tmp;
sscanf ( num.c_str(), "%lf" , &tmp);
return tmp;
}
Cette réponse se confirme dans vos commentaires. Je soupçonne profondément que vous n’affichez pas correctement le résultat.
J'ai eu exactement la même chose qui m'est arrivée une fois. J'ai passé une journée entière à essayer de comprendre pourquoi j'obtenais une mauvaise valeur dans un int 64 bits, pour découvrir que printf ignorait le deuxième octet. Vous ne pouvez pas simplement passer une valeur 64 bits dans printf comme un int.
Quant à savoir pourquoi atof()ne fonctionne pas dans la question initiale: le fait qu'elle soit doublée me rend suspect. Le code ne doit pas être compilé sans #include <stdlib.h>, mais si le cast a été ajouté pour résoudre un avertissement de compilation, il atof()n'est pas correctement déclaré. Si le compilateur suppose qu'il atof()renvoie un int, le cast résoudra l'avertissement de conversion, mais cela ne fera pas reconnaître la valeur de retour comme un double.
#include <stdlib.h>
#include <string>
...
std::string num = "0.6";
double temp = atof(num.c_str());
devrait fonctionner sans avertissement.
Plutôt que de faire glisser Boost dans l'équation, vous pouvez conserver votre chaîne (temporairement) en tant que char[]et l'utiliser sprintf().
Mais bien sûr, si vous utilisez de toute façon Boost, ce n'est vraiment pas trop un problème.
Vous ne voulez pas Boost lexical_cast pour la chaîne <-> virgule flottante de toute façon. Ce sous-ensemble de cas d'utilisation est le seul ensemble pour lequel le boost est systématiquement pire que les anciennes fonctions - et ils ont essentiellement concentré tous leurs échecs là-bas, car leurs propres résultats de performances montrent des performances 20-25X PLUS LENT que l'utilisation de sscanf et printf pour de telles conversions.
Google vous-même. boost :: lexical_cast peut gérer quelque chose comme 50 conversions et si vous excluez celles impliquant des # virgules flottantes, c'est aussi bon ou meilleur que les alternatives évidentes (avec l'avantage supplémentaire d'avoir une seule API pour toutes ces opérations). Mais apportez des flotteurs et c'est comme le Titanic frappant un iceberg en termes de performances.
Les anciennes fonctions str-> double dédiées peuvent toutes faire 10000 analyses en quelque chose comme 30 ms (ou mieux). lexical_cast prend environ 650 ms pour faire le même travail.
Mon problème:
Ma solution (utilise la fonction 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 ... m'a pris assez de temps pour arriver à cette solution. Et j'ai toujours le sentiment de ne pas en savoir assez sur la localisation des cordes et tout ça ...