How can I convert a std::string to int?
快问一个问题。我环顾了一下互联网,找到了一些解决方案,但都没有奏效。看看把一个字符串转换成一个int,我的意思不是ASCII码。
为了进行快速的向下搜索,我们以字符串的形式传递一个方程。我们要把它分解,正确格式化,解线性方程组。现在,这么说,我无法将字符串转换为int。
我知道字符串的格式是(-5)或(25)等,所以它绝对是一个int,但是我们如何从字符串中提取它呢?
我想的一种方法是在字符串中运行for/while循环,检查一个数字,然后提取后面的所有数字,然后查看是否有前导的'-',如果有,将int乘以-1。
不过,对于这样一个小问题来说,这似乎有点过于复杂了。有什么想法吗?
在C++ 11中,有一些不错的新的转换函数,从EDCOX1,4,到数字类型。
因此,而不是
1 | atoi( str.c_str() ) |
你可以使用
1 | std::stoi( str ) |
其中,
有各种口味的数字版本:
1 2 | std::istringstream ss(thestring); ss >> thevalue; |
要完全正确,您需要检查错误标志。
使用atoi函数将字符串转换为整数:
1 2 3 | string a ="25"; int b = atoi(a.c_str()); |
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
可能的选项如下所述:
1。第一个选项:SScanf()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #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。第二种选择:STD::STO*()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #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兼容编译器上使用。
三。第三种选择:S流
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #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。第四种选择:Boost的词法转换
1 2 3 4 5 6 7 8 9 10 11 12 | #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来更好地管理错误(请参见此处)。
5。第五个选项:strto*()
由于错误管理,此解决方案非常长,本文将对此进行描述。由于没有函数返回一个普通的int,所以在使用整数的情况下需要进行转换(有关如何实现此转换的信息,请参阅此处)。
6。第六个选项:qt
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #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::StIO(),或者作为第二个选项,使用Qt库。所有其他的解决方案都是不鼓励的或有缺陷的。
Boost.Lexical_Cast怎么样?
以下是他们的例子:
The following example treats command line arguments as a sequence of numeric data:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | 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); } } ... } |
诚然,我的解决方案不适用于负整数,但它将从包含整数的输入文本中提取所有正整数。它利用
1 2 3 4 5 6 7 | 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; } |
输入文本:
1 | the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878 |
输出整数:
1 2 3 4 5 | 5 25 7987 78 9878 |
1 2 3 4 5 6 7 8 9 10 11 12 13 | 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
可能有点过分了,但是
我的代码:
1 2 3 4 5 6 7 8 9 10 11 | #include <iostream> using namespace std; int main() { string s="32"; //String int n=stoi(s); //Convert to int cout << n + 1 << endl; return 0; } |
从http://///stoi www.cplusplus.com字符串参考号
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | // 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) <<"] "; std::cout << str_hex <<":" << i_hex << ' '; std::cout << str_bin <<":" << i_bin << ' '; std::cout << str_auto <<":" << i_auto << ' '; return 0; } |
输出:
2001年,太空奥德赛:2001太空奥德赛]和[,
40c3:16579
- 10010110001:1201
0x7F):127
嗯,很多答案,很多可能性。我这里缺少的是一些将字符串转换成不同C++整数类型(String,int,Load,Boo..…)的通用方法。我提出了以下解决方案:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | #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; } |
以下是用法示例:
1 2 3 4 5 6 7 8 9 10 11 12 | 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时:
1 2 3 | stringstream ss(str); int x; ss >> x; |
x变为2147483647,这绝对是一个错误:字符串"2147483648"不应该转换为int 2147483647。提供给integraltype的函数发现此类错误并引发异常。
在Windows中,您可以使用:
1 2 3 4 5 6 7 8 9 10 11 12 | 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 <<" "; } if (StrToIntEx(dec.c_str(), STIF_SUPPORT_HEX, &ret)) { std::cout << ret <<" "; } |
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
一个在线版:
(
你可以到这个链接,指的是
的核心思想是使用
由于
一个例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | #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; } |
这将输出:
1 2 3 4 | 1111000001011010 61530 f05a 1111000001011010 |
还有一个简单的方法:假设您有一个像
第一:INQ
q=q-48; remember that adding 48 to digits is their ascii code .
第二种方法:
这通常在我使用它时起作用:
1 | int myint = int::Parse(mystring); |