如何判断c函数atoi是否失败或者是否是一串零?

时间:2009-10-28 23:10:45

标签: c++ atoi

当使用函数atoi(或strtol或类似函数)时,如何判断整数转换是否失败或者转换的C字符串是否为{{ 1}}?

对于我正在做的事情,0是可接受的值,转换的C字符串可能包含任意数量的0 s。它也可能有领先的空白。

6 个答案:

答案 0 :(得分:43)

正确的功能(只要你坚持使用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'确保数字后面没有任何内容。如果要在实际数字(空格?)之后允许其他字符,则必须相应地修改此检查。

P.S。我稍后添加了end == number检查以捕获空输入序列。单独*end != '\0'检查就会发现“所有空白”和“根本没有数字”输入。尽管提前捕获空输入可能是有意义的。在这种情况下,end == number检查将/可能变得不必要。

答案 1 :(得分:23)

由于此标记为

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; 
}

答案 2 :(得分:8)

对于C ++ 11及更高版本:

字符串到整数转换的转到函数现在是stoi,它接受​​string并返回int,或者在出错时抛出异常。

不再需要在已接受的答案中提及的详细istringstream黑客。

(还有stol / stoll / stof / stod / stold long / long long分别是/ float / double / long double次转化。)

答案 3 :(得分:5)

来自strtol()的手册页:

  

如果endptr不为NULL,则strtol()存储第一个无效的地址        * endptr中的字符。但是,如果根本没有数字,strtol()        将nptr的原始值存储在* endptr中。 (因此,如果* nptr不是        '\0'但返回时** endptr为'\0',整个字符串都有效。)

答案 4 :(得分:2)

strtol的替代方案是sscanf,虽然它有点重量级:

const char *numStr = "12345";  // input string
int value;
if(sscanf(numStr, "%d", &value) == 1)
    ;  // parsing succeeded, use value
else
    ;  // error

然而,这允许你的字符串中的前导空格(可能是也可能不是这样),它允许任何东西跟踪数字,因此“123abc”将被接受并返回123.如果你想要更严格的控制,与strtol()一起使用AndreyT demonstrates

答案 5 :(得分:1)

自从我完成了C / C ++已经有一段时间了,但在我看来(过于简单)的解决方案就是只检查字符串为“0”。

int value = atoi(string_number.c_str());

if ( !value && string_number != "0" ) {
  // error
} else {
  // great success!
}