我如何判断 c 函数 atoi 是失败还是一串零?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1640720/
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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 20:43:04  来源:igfitidea点击:

How do I tell if the c function atoi failed or if it was a string of zeros?

c++atoi

提问by Jared

When using the function atoi(or strtolor similar functions for that matter), how can you tell if the integer conversion failed or if the C-string that was being converted was a 0?

在使用该函数atoi(或strtol与此相关的类似函数)时,如何判断整数转换是否失败,或者正在转换的 C 字符串是否为0?

For what I'm doing, 0is an acceptable value and the C-string being converted may contain any number of 0s. It may also have leading whitespace.

对于我正在做的事情,0是一个可接受的值,并且正在转换的 C 字符串可能包含任意数量的0s。它也可能有前导空格。

采纳答案by emlai

For C++11 and later:

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

The go-to function for string-to-integer conversion is now stoi, which takes a stringand returns an int, or throws an exception on error.

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

No need for the verbose istringstreamhack mentioned in the accepted answer anymore.

不再需要istringstream接受的答案中提到的冗长的黑客攻击。

(There's also stol/stoll/stof/stod/stoldfor long/long long/float/double/long doubleconversions, respectively.)

(还有stol/ stoll/ stof/ stod/ 分别stold用于long/ long long/ float/ double/long double转换。)

回答by AnT

The proper function (as long as you are insisting on using C-style functions) is strtoland the conversion code might look as follows

正确的函数(只要你坚持使用 C 风格的函数)是strtol,转换代码可能如下所示

const char *number = "10"; /* for example */

char *end;
long value = strtol(number, &end, 10); 
if (end == number || *end != '
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; 
}
' || errno == ERANGE) /* ERROR, abort */; /* Success */ /* Add whatever range checks you want to have on the value of `value` */

Some remarks:

一些备注:

strtolallows (meaning: quietly skips) whitespace in front of the actual number. If you what to treat such leading whitespace as an error, you have to check for it yourself.

strtol允许(意思是:悄悄地跳过)实际数字前面的空格。如果您将这种前导空格视为错误,您必须自己检查。

The check for *end != '\0'makes sure that there's nothing after the digits. If you want to permit other characters after the actual number (whitespace?), this check has to be modified accordingly.

检查*end != '\0'确保数字后没有任何内容。如果您想在实际数字(空格?)之后允许其他字符,则必须相应地修改此检查。

P.S. I added the end == numbercheck later to catch empty input sequences. "All whitespace" and "no number at all" inputs would have been caught by *end != '\0'check alone. It might make sense to catch empty input in advance though. In that case end == numbercheck will/might become unnecessary.

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

回答by sbi

Since this is tagged c++:

由于这是标记为c++

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

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

回答by Oleksandr Tymoshenko

From the man page for strtol():

从 strtol() 的手册页:

If endptr is not NULL, strtol() stores the address of the first invalid character in *endptr. If there were no digits at all, however, strtol() stores the original value of nptr in *endptr. (Thus, if *nptr is not '\0'but **endptr is '\0'on return, the entire string was valid.)

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

回答by Justin Johnson

It's been a while since I've done and C/C++, but it would appear to me that the (overly) simple solution would be to check just the string for "0".

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

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

回答by Adam Rosenfield

An alternative to strtolis sscanf, although it's a little heavy-weight:

的替代方法strtolsscanf,虽然它有点重量级:

##代码##

However, this allows leading whitespace in your string (which may or may not be desirable), and it allows anything to trail the number, so "123abc" would be accepted and return 123. If you want to have tighter control, go with strtol(), as AndreyT demonstrates.

但是,这允许在您的字符串中使用前导空格(可能需要也可能不需要),并且它允许任何内容尾随数字,因此将接受“123abc”并返回 123。如果您想进行更严格的控制,请使用strtol(),正如AndreyT 所展示的那样