ちょっと質問があります。私はインターネットをかなり見回し、いくつかの解決策を見つけましたが、どれもまだうまくいきませんでした。文字列をint型に変換することを検討していて、ASCIIコードを意味するのではありません。
手短に言うと、式として文字列として渡されます。それを分解して正しくフォーマットし、線形方程式を解きます。さて、それを言って、私は文字列をintに変換することができません。
私は、文字列が(-5)か(25)などのフォーマットになることを知っているので、それは間違いなくintです。しかし、文字列からそれをどのように抽出するのでしょうか。
私が考えていた1つの方法は、文字列をfor/whileループで実行し、数字をチェックし、それ以降のすべての数字を抽出してから、先頭に ' - 'があったかどうか1。
とはいえ、このような小さな問題では少し複雑すぎるようです。何か案は?
C++ 11には、std::string
から数値型への素敵な新しい変換関数がいくつかあります。
の代わりに
atoi( str.c_str() )
使用できます
std::stoi( str )
ここで、str
はstd::string
としての番号です。
番号のすべてのフレーバーのバージョンがあります:long stol(string)
、float stof(string)
、double stod(string)
、... http://en.cppreference.com/w/cpp/stringを参照してください/ basic_string/stol
std::istringstream ss(thestring);
ss >> thevalue;
完全に正しくするには、エラーフラグを確認します。
atoi関数を使用して文字列を整数に変換します。
string a = "25";
int b = atoi(a.c_str());
可能なオプションは次のとおりです。
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の一部のバージョンで巨大な入力データでクラッシュする可能性がある"( here を参照) =、および ここ )。
2。 2番目のオプション:std :: sto *()
#include <iostream>
#include <string>
int i;
float f;
double d;
std::string str;
try {
// string -> integer
int i = std::stoi(s);
// string -> float
float f = std::stof(s);
// string -> double
double d = std::stod(s);
} 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 ??
ただし、このソリューションでは、不正な入力を区別するのは困難です( here を参照)。
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のラッパーであり、ドキュメントでは、エラー管理を改善するためにsstremを使用することを提案しています( here を参照)。
5。 5番目のオプション:strto *()
このソリューションは、エラー管理のために非常に長いため、ここで説明します。プレーンなintを返す関数はないため、整数の場合は変換が必要です(この変換を実現する方法については here を参照してください)。
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ライブラリを使用することです。他のすべてのソリューションは推奨されないか、バグがあります。
Boost.Lexical_cast はどうですか。
これが彼らの例です。
次の例では、コマンドライン引数を一連の数値データとして扱います。
int main(int argc, char * argv[])
{
using boost::lexical_cast;
using boost::bad_lexical_cast;
std::vector<short> args;
while(*++argv)
{
try
{
args.Push_back(lexical_cast<short>(*argv));
}
catch(bad_lexical_cast &)
{
args.Push_back(0);
}
}
...
}
確かに、私の解決策は負の整数に対してはうまくいきませんが、整数を含む入力テキストからすべての正の整数を抽出します。 numeric_only
ロケールを利用します。
int main() {
int num;
std::cin.imbue(std::locale(std::locale(), new numeric_only()));
while ( std::cin >> num)
std::cout << num << std::endl;
return 0;
}
入力テキスト:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878
出力整数:
5
25
7987
78
9878
クラスnumeric_only
は次のように定義されています。
struct numeric_only: std::ctype<char>
{
numeric_only(): std::ctype<char>(get_table()) {}
static std::ctype_base::mask const* get_table()
{
static std::vector<std::ctype_base::mask>
rc(std::ctype<char>::table_size,std::ctype_base::space);
std::fill(&rc['0'], &rc[':'], std::ctype_base::digit);
return &rc[0];
}
};
完全なオンラインデモ: http://ideone.com/dRWSj
それはおそらく少しやり過ぎですが、 boost::lexical_cast<int>( theString )
は仕事にかなりうまくいくはずです。
Windowsでは、あなたは使用することができます:
const std::wstring hex = L"0x13";
const std::wstring dec = L"19";
int ret;
if (StrToIntEx(hex.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "\n";
}
if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) {
std::cout << ret << "\n";
}
strtol
、stringstream
は、16進数を解釈する必要がある場合は基数を指定する必要があります。
atoi
は、文字列が整数表現で始まると仮定して、文字列を整数に変換する組み込み関数です。
私のコード:
#include <iostream>
using namespace std;
int main()
{
string s="32"; //String
int n=stoi(s); //Convert to int
cout << n + 1 << endl;
return 0;
}
まあ、たくさんの答え、たくさんの可能性。ここで欠けているのは、文字列をさまざまなC++整数型(short、int、long、boolなど)に変換する汎用的な方法です。私は以下の解決策を思いついた。
#include<sstream>
#include<exception>
#include<string>
#include<type_traits>
using namespace std;
template<typename T>
T toIntegralType(const string &str) {
static_assert(is_integral<T>::value, "Integral type required.");
T ret;
stringstream ss(str);
ss >> ret;
if ( to_string(ret) != str)
throw invalid_argument("Can't convert " + str);
return ret;
}
使用例は次のとおりです。
string str = "123";
int x = toIntegralType<int>(str); // x = 123
str = "123a";
x = toIntegralType<int>(str); // throws exception, because "123a" is not int
str = "1";
bool y = toIntegralType<bool>(str); // y is true
str = "0";
y = toIntegralType<bool>(str); // y is false
str = "00";
y = toIntegralType<bool>(str); // throws exception
文字列を整数型に変換するのにstringstream出力演算子を使用しないのはなぜですか?これが答えです。文字列に、目的の整数型の制限を超える値が含まれるとします。一例として、Wndows 64ではmax intは2147483647です。文字列にmax int + 1という値を代入しましょう:string str = "2147483648"。 では、文字列をintに変換すると
stringstream ss(str);
int x;
ss >> x;
xは2147483647になりますが、これは間違いなくエラーです。文字列 "2147483648"はint 2147483647に変換されることは想定されていませんでした。
http://www.cplusplus.com/reference/string/stoi/ から
// stoi example
#include <iostream> // std::cout
#include <string> // std::string, std::stoi
int main ()
{
std::string str_dec = "2001, A Space Odyssey";
std::string str_hex = "40c3";
std::string str_bin = "-10010110001";
std::string str_auto = "0x7f";
std::string::size_type sz; // alias of size_t
int i_dec = std::stoi (str_dec,&sz);
int i_hex = std::stoi (str_hex,nullptr,16);
int i_bin = std::stoi (str_bin,nullptr,2);
int i_auto = std::stoi (str_auto,nullptr,0);
std::cout << str_dec << ": " << i_dec << " and [" << str_dec.substr(sz) << "]\n";
std::cout << str_hex << ": " << i_hex << '\n';
std::cout << str_bin << ": " << i_bin << '\n';
std::cout << str_auto << ": " << i_auto << '\n';
return 0;
}
出力:
2001、A Space Odyssey:2001と[、A Space Odyssey]
40c3:16579
-10010110001:-1201
0x7f:127
ll toll(string a){
ll ret=0;
bool minus=false;
for(auto i:a){
if(i=='-'){ minus=true; continue; }
ret*=10;
ret+=(i-'0');
} if(minus) ret*=-1;
return ret;
# ll is defined as, #define ll long long int
# usage: ll a = toll(string("-1234"));
}
一行バージョン:long n = strtol(s.c_str(), NULL, base);
。
(s
は文字列、base
は2、8、10、16などのint
です。)
strtol
の詳細については このリンク を参照してください。
基本的な考え方は、 strtol
functionを使用することです。これはcstdlib
に含まれています。
strtol
はchar
配列でのみ処理するので、string
をchar
配列に変換する必要があります。 このリンク を参照できます。
例:
#include <iostream>
#include <string> // string type
#include <bitset> // bitset type used in the output
int main(){
s = "1111000001011010";
long t = strtol(s.c_str(), NULL, 2); // 2 is the base which parse the string
cout << s << endl;
cout << t << endl;
cout << hex << t << endl;
cout << bitset<16> (t) << endl;
return 0;
}
出力されます:
1111000001011010
61530
f05a
1111000001011010