编辑:在c++17或更高版本from_chars
中是首选。请参阅此处了解更多信息:https ://topanswers.xyz/cplusplus?q=724#a839
对于给定的string str
,有几种方法可以实现这一点,每种方法都有优点和缺点。我在这里写了一个活生生的例子:https ://ideone.com/LO2Qnq并在下面讨论每个:
正如这里 strtol
所建议的,可以使用 out-parameter 来获取读取的字符数。strtol
实际上返回 a long
not anint
所以在返回时会发生强制转换。
char* size;
const int num = strtol(str.c_str(), &size, 10);
if(distance(str.c_str(), const_cast<const char*>(size)) == str.size()) {
cout << "strtol: " << num << endl;
} else {
cout << "strtol: error\n";
}
请注意,这用于str.c_str()
引用相同的字符串。c_str
如果您有 C++11,则返回指向用作字符存储的底层数组的指针,而不是临时的:
c_str()
并data()
执行相同的功能
另请注意,返回的指针c_str
将在strtol
anddistance
调用之间有效,除非:
- 将非
const
引用传递string
给任何标准库函数
- 在、、、、、、和上调用非
const
成员函数string
operator[]
at()
front()
back()
begin()
rbegin()
end()
rend()
如果您违反其中任何一种情况,您需要制作i
' 底层证券的临时副本const char*
并对其进行测试。
sscanf
可以%zn
用来返回读取的字符数,这可能比进行指针比较更直观。如果基础很重要,sscanf
可能不是一个好的选择。与支持基数 2 - 36 不同,strtol
它只为八进制 ( )、十进制 ( ) 和十六进制 ( ) 提供说明符。stoi
sscanf
%o
%d
%x
size_t size;
int num;
if(sscanf(str.c_str(), "%d%zn", &num, &size) == 1 && size == str.size()) {
cout << "sscanf: " << num << endl;
} else {
cout << "sscanf: error\n";
}
正如这里 stoi
所建议的,输出参数的工作方式类似于返回读取sscanf
的%n
字符数。与 C++ 保持一致,这需要 astring
并且与上面的 C 实现不同,如果第一个非空白字符不被视为当前基数的数字,则stoi
抛出一个invalid_argument
,不幸的是,这意味着与 C 实现不同,这必须检查两者中的错误try
和catch
块。
try {
size_t size;
const auto num = stoi(str, &size);
if(size == str.size()) {
cout << "stoi: " << num << endl;
} else {
throw invalid_argument("invalid stoi argument");
}
} catch(const invalid_argument& /*e*/) {
cout << "stoi: error\n";
}