可能なオプションは次のとおりです。
1.最初のオプション: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
これはエラーです(cppcheckでも表示されます)。「フィールド幅の制限のないscanfは、libcの一部のバージョンで巨大な入力データを使用するとクラッシュする可能性があります」(こことここを参照)。
2. 2番目のオプション: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
}
このソリューションは短くエレガントですが、C ++ 11準拠のコンパイラでのみ使用できます。
3. 3番目のオプション: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 ??
ただし、このソリューションでは、不適切な入力を区別することは困難です(参照 ここを)。
4. 4番目のオプション:Boostのlexical_cast
#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
}
ただし、これはのラッパーにすぎsstream
ず、ドキュメントではsstream
エラー管理を改善ため(ここを参照)。
5. 5番目のオプション:strto *()
エラー管理のため、このソリューションは非常に長く、ここで説明します。プレーンなintを返す関数はないため、整数の場合は変換が必要です(参照)この変換を行う方法こちらを)。
6. 6番目のオプション: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
結論
要約すると、最良のソリューションはC ++ 11、std::stoi()
または2番目のオプションとしてQtライブラリの使用です。他のすべての解決策は、推奨されないか、バグがあります。
atoi()
か?