Les options possibles sont décrites ci-dessous:
1. Première option: sscanf ()
#include <cstdio>
#include <string>
int i;
float f;
double d;
std::string str;
// string -> integer
if(sscanf(str.c_str(), "%d", &i) != 1)
// error management
// string -> float
if(sscanf(str.c_str(), "%f", &f) != 1)
// error management
// string -> double
if(sscanf(str.c_str(), "%lf", &d) != 1)
// error management
Il s'agit d'une erreur (également affichée par cppcheck) car "scanf sans limites de largeur de champ peut planter avec d'énormes données d'entrée sur certaines versions de libc" (voir ici et ici ).
2. Deuxième option: std :: sto * ()
#include <iostream>
#include <string>
int i;
float f;
double d;
std::string str;
try {
// string -> integer
int i = std::stoi(str);
// string -> float
float f = std::stof(str);
// string -> double
double d = std::stod(str);
} catch (...) {
// error management
}
Cette solution est courte et élégante, mais elle n'est disponible que sur les compilateurs compatibles C ++ 11.
3. Troisième option: sstreams
#include <string>
#include <sstream>
int i;
float f;
double d;
std::string str;
// string -> integer
std::istringstream ( str ) >> i;
// string -> float
std::istringstream ( str ) >> f;
// string -> double
std::istringstream ( str ) >> d;
// error management ??
Cependant, avec cette solution, il est difficile de distinguer les mauvaises entrées (voir ici ).
4. Quatrième option: lexical_cast de Boost
#include <boost/lexical_cast.hpp>
#include <string>
std::string str;
try {
int i = boost::lexical_cast<int>( str.c_str());
float f = boost::lexical_cast<int>( str.c_str());
double d = boost::lexical_cast<int>( str.c_str());
} catch( boost::bad_lexical_cast const& ) {
// Error management
}
Cependant, ce n'est qu'un wrapper de sstream
, et la documentation suggère d'utiliser sstream
pour une meilleure gestion des erreurs (voir ici ).
5. Cinquième option: strto * ()
Cette solution est très longue, en raison de la gestion des erreurs, et elle est décrite ici. Comme aucune fonction ne renvoie un entier simple, une conversion est nécessaire en cas d'entier (voir ici comment cette conversion peut être réalisée).
6. Sixième option: Qt
#include <QString>
#include <string>
bool ok;
std::string;
int i = QString::fromStdString(str).toInt(&ok);
if (!ok)
// Error management
float f = QString::fromStdString(str).toFloat(&ok);
if (!ok)
// Error management
double d = QString::fromStdString(str).toDouble(&ok);
if (!ok)
// Error management
Conclusions
En résumé, la meilleure solution est C ++ 11 std::stoi()
ou, comme deuxième option, l'utilisation de bibliothèques Qt. Toutes les autres solutions sont déconseillées ou boguées.
atoi()
?