C++ 如何将 std::string 转换为 int?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/7663709/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How can I convert a std::string to int?
提问by Brandon
Just have a quick question. I've looked around the internet quite a bit and I've found a few solutions but none of them have worked yet. Looking at converting a string to an int and I don't mean ASCII codes.
只是有一个快速的问题。我在互联网上看了很多,我找到了一些解决方案,但没有一个有效。考虑将字符串转换为 int,我不是指 ASCII 代码。
For a quick run-down, we are passed in an equation as a string. We are to break it down, format it correctly and solve the linear equations. Now, in saying that, I'm not able to convert a string to an int.
为了快速了解,我们以字符串形式传入一个等式。我们要把它分解,正确格式化并解出线性方程。现在,说到这里,我无法将字符串转换为 int。
I know that the string will be in either the format (-5) or (25) etc. so it's definitely an int. But how do we extract that from a string?
我知道字符串将采用 (-5) 或 (25) 等格式,所以它绝对是一个整数。但是我们如何从字符串中提取它呢?
One way I was thinking is running a for/while loop through the string, check for a digit, extract all the digits after that and then look to see if there was a leading '-', if there is, multiply the int by -1.
我想的一种方法是在字符串中运行 for/while 循环,检查一个数字,然后提取所有数字,然后查看是否有前导“-”,如果有,将 int 乘以 - 1.
It seems a bit over complicated for such a small problem though. Any ideas?
不过对于这样一个小问题来说似乎有点过于复杂了。有任何想法吗?
回答by tgmath
In C++11 there are some nice new convert functions from std::string
to a number type.
在 C++11 中,有一些不错的新的从std::string
数字类型转换为数字类型的函数。
So instead of
所以代替
atoi( str.c_str() )
you can use
您可以使用
std::stoi( str )
where str
is your number as std::string
.
str
你的号码在哪里std::string
?
There are version for all flavours of numbers:
long stol(string)
, float stof(string)
, double stod(string)
,...
see http://en.cppreference.com/w/cpp/string/basic_string/stol
有适用于所有数字的版本:
long stol(string)
, float stof(string)
, double stod(string)
,... 参见http://en.cppreference.com/w/cpp/string/basic_string/stol
回答by Winston Ewert
std::istringstream ss(thestring);
ss >> thevalue;
To be fully correct you'll want to check the error flags.
为了完全正确,您需要检查错误标志。
回答by Claudio
The possible options are described below:
可能的选项如下所述:
1. First option: sscanf()
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
This is an error (also shown by cppcheck) because "scanf without field width limits can crash with huge input data on some versions of libc"(see here, and here).
这是一个错误(也由 cppcheck 显示),因为“在某些版本的 libc 上,没有字段宽度限制的 scanf 可能会因大量输入数据而崩溃”(请参阅此处和此处)。
2. Second option: std::sto*()
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
}
This solution is short and elegant, but it is available only on on C++11 compliant compilers.
此解决方案简短而优雅,但仅适用于符合 C++11 的编译器。
3. Third option: sstreams
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 ??
However, with this solution is hard to distinguish between bad input (see here).
但是,使用此解决方案很难区分错误输入(请参阅此处)。
4. Fourth option: Boost's lexical_cast
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
}
However, this is just a wrapper of sstream
, and the documentation suggests to use sstream
for better error management (see here).
但是,这只是 的包装器sstream
,文档建议sstream
用于更好的错误管理(请参阅此处)。
5. Fifth option: strto*()
5. 第五个选项:strto*()
This solution is very long, due to error management, and it is described here. Since no function returns a plain int, a conversion is needed in case of integer (see herefor how this conversion can be achieved).
由于错误管理,此解决方案很长,在此处进行描述。由于没有函数返回普通的 int,因此在整数的情况下需要进行转换(有关如何实现此转换,请参见此处)。
6. Sixth option: Qt
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
Conclusions
结论
Summing up, the best solution is C++11 std::stoi()
or, as a second option, the use of Qt libraries. All other solutions are discouraged or buggy.
总而言之,最好的解决方案是 C++11,std::stoi()
或者作为第二个选择,使用 Qt 库。所有其他解决方案都是不鼓励或有问题的。
回答by brenjt
use the atoi function to convert the string to an integer:
使用 atoi 函数将字符串转换为整数:
string a = "25";
int b = atoi(a.c_str());
回答by Rob?
What about Boost.Lexical_cast?
Here is their example:
这是他们的例子:
The following example treats command line arguments as a sequence of numeric data:
以下示例将命令行参数视为数字数据序列:
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);
}
}
...
}
回答by Nawaz
Admittedly, my solution wouldn't work for negative integers, but it will extract all positive integers from input text containing integers. It makes use of numeric_only
locale:
诚然,我的解决方案不适用于负整数,但它会从包含整数的输入文本中提取所有正整数。它使用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;
}
Input text:
输入文本:
the format (-5) or (25) etc... some text.. and then.. 7987...78hjh.hhjg9878
Output integers:
输出整数:
5
25
7987
78
9878
The class numeric_only
is defined as:
该类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];
}
};
Complete online demo : http://ideone.com/dRWSj
完整的在线演示:http: //ideone.com/dRWSj
回答by James Kanze
It's probably a bit of overkill, but
boost::lexical_cast<int>( theString )
should to the job
quite well.
这可能有点矫枉过正,但
boost::lexical_cast<int>( theString )
应该很好地完成工作。
回答by Eric
atoi
is a built-in function that converts a string to an integer, assuming that the string begins with an integer representation.
atoi
是一个将字符串转换为整数的内置函数,假设字符串以整数表示形式开始。
回答by Jichao
In Windows, you could use:
在 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
need to specify the base if you need to interpret hexdecimal.
strtol
,stringstream
如果需要解释十六进制,需要指定基数。
回答by Andrushenko Alexander
Well, lot of answers, lot of possibilities. What I am missing here is some universal method that converts a string to different C++ integral types (short, int, long, bool, ...). I came up with following solution:
嗯,很多答案,很多可能性。我在这里缺少的是一些将字符串转换为不同 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;
}
Here are examples of usage:
以下是使用示例:
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
Why not just use stringstream output operator to convert a string into an integral type? Here is the answer: Let's say a string contains a value that exceeds the limit for intended integral type. For examle, on Wndows 64 max int is 2147483647. Let's assign to a string a value max int + 1: string str = "2147483648". Now, when converting the string to an int:
为什么不直接使用 stringstream 输出运算符将字符串转换为整数类型?答案如下:假设一个字符串包含一个超出预期整数类型限制的值。例如,在 Wndows 64 上,max int 是 2147483647。让我们为字符串分配一个值 max int + 1:string str = "2147483648"。现在,将字符串转换为 int 时:
stringstream ss(str);
int x;
ss >> x;
x becomes 2147483647, what is definitely an error: string "2147483648" was not supposed to be converted to the int 2147483647. The provided function toIntegralType spots such errors and throws exception.
x 变为 2147483647,这绝对是一个错误:字符串“2147483648”不应该被转换为 int 2147483647。提供的函数 toIntegralType 会发现此类错误并抛出异常。