Le possibili opzioni sono descritte di seguito:
1. Prima opzione: 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
Questo è un errore (mostrato anche da cppcheck) perché "scanf senza limiti di larghezza di campo può andare in crash con enormi dati di input su alcune versioni di libc" (vedi qui e qui ).
2. Seconda opzione: 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
}
Questa soluzione è breve ed elegante, ma è disponibile solo su compilatori conformi a C ++ 11.
3. Terza opzione: stream
#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 ??
Tuttavia, con questa soluzione è difficile distinguere tra input errato (vedere qui ).
4. Quarta opzione: lexical_cast di 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
}
Tuttavia, questo è solo un wrapper di sstream
e la documentazione suggerisce di utilizzare sstream
per una migliore gestione degli errori (vedi qui ).
5. Quinta opzione: strto * ()
Questa soluzione è molto lunga, a causa della gestione degli errori, ed è descritta qui. Poiché nessuna funzione restituisce un semplice int, è necessaria una conversione in caso di numero intero (vedere qui per come è possibile ottenere questa conversione).
6. Sesta opzione: 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
conclusioni
Riassumendo, la soluzione migliore è C ++ 11 std::stoi()
o, come seconda opzione, l'uso delle librerie Qt. Tutte le altre soluzioni sono scoraggiate o buggy.
atoi()
?