当使用功能atoi
(或strtol
或与此有关的类似功能),你怎么能告诉我们,如果整数转换失败,或者如果正被转换的C-字符串是0
?
对于我在做什么, 0
是一个可接受的值和C-串被转换可以包含任意数量的0
秒。 它也可以有前导空格。
当使用功能atoi
(或strtol
或与此有关的类似功能),你怎么能告诉我们,如果整数转换失败,或者如果正被转换的C-字符串是0
?
对于我在做什么, 0
是一个可接受的值和C-串被转换可以包含任意数量的0
秒。 它也可以有前导空格。
去到的字符串到整数转换功能现在是stoi
,它接受一个string
,并返回一个int
,或错误抛出异常。
无需冗长的istringstream
在接受答复中提到了黑客攻击。
(有也是stol
/ stoll
/ stof
/ stod
/ stold
为long
/ long long
/ float
/ double
/ long double
转换,分别)。
正确功能(只要你在使用C风格的函数坚持)是strtol
并遵循转换代码可能如下
const char *number = "10"; /* for example */
char *end;
long value = strtol(number, &end, 10);
if (end == number || *end != '\0' || errno == ERANGE)
/* ERROR, abort */;
/* Success */
/* Add whatever range checks you want to have on the value of `value` */
一些言论:
strtol
允许(意味着:悄悄跳过)空白在实际数字前面。 如果您有什么治疗这种前导空格作为一个错误,你必须检查它自己。
在检查*end != '\0'
可以确保有数字后,没有什么是。 如果你想允许实际数量(空白?)后其他字符,此检查必须进行相应的修改。
PS我添加了end == number
检查后赶上空的输入序列。 “所有的空白”和“无数量在所有”投入将已陷入由*end != '\0'
单独检查。 它可能是有意义的追赶空预先输入虽然。 在这种情况下, end == number
检查会/可能变得不必要。
由于该被标记C ++ :
template< typename T >
inline T convert(const std::string& str)
{
std::istringstream iss(str);
T obj;
iss >> std::ws >> obj >> std::ws;
if(!iss.eof())
throw "dammit!";
return obj;
}
从与strtol()的手册页:
•若endptr不为NULL,与strtol()保存在* endptr第一个无效字符的地址。 如果没有数字可言,但是,与strtol()存储NPTR在* endptr原始值。 (因此,如果* NPTR不是
'\0'
,但** endptr是'\0'
的回报,整个字符串是有效的。)
以另一种strtol
是sscanf
,虽然这是一个有点沉重,重量:
const char *numStr = "12345"; // input string
int value;
if(sscanf(numStr, "%d", &value) == 1)
; // parsing succeeded, use value
else
; // error
然而,这可以让你的字符串是空白(这可能会或可能不是理想的),它允许任何对TRAIL的数量,因此“123ABC”将被接受,并返回123。如果你想有更严格的控制,去strtol()
作为AndreyT演示 。
它已经有一段时间,因为我已经做了和C / C ++,但它似乎对我来说,(过分)简单的解决办法是检查只是为“0”的字符串。
int value = atoi(string_number.c_str());
if ( !value && string_number != "0" ) {
// error
} else {
// great success!
}