字符串中的非整数数字并使用atoi

mon*_*ksy 2 c c++ math atoi

如果字符串中有非数字字符并且您调用atoi [我假设wtoi将执行相同的操作].atoi将如何处理字符串?

让我们举一个例子,我有以下字符串:

  1. "20234543"
  2. "232B"
  3. "B"

我确定1将返回整数20234543.我很好奇的是,如果2将返回"232".[多数民众赞成我需要解决我的问题].3也不应返回值.这些信念是错误的吗?另外......如果2确实按我的意思行事,它如何处理字符串末尾的e字符?[这通常以指数表示法使用]

Alo*_*hal 9

根据该标准,"功能atof,atoi,atol,和atoll需要不影响整数表达式的值errno上的误差.如果结果的值不能表示,该行为是未定义".(7.20.1,C99中的数字转换功能).

所以,从技术上讲,任何事都可能发生.即使对于第一种情况,由于INT_MAX保证至少为32767,并且由于20234543大于此,因此它也可能失败.

为了更好地检查错误,请使用strtol:

const char *s = "232B";
char *eptr;
long value = strtol(s, &eptr, 10); /* 10 is the base */
/* now, value is 232, eptr points to "B" */

s = "20234543";
value = strtol(s, &eptr, 10);

s = "123456789012345";
value = strtol(s, &eptr, 10);
/* If there was no overflow, value will contain 123456789012345,
   otherwise, value will contain LONG_MAX and errno will be ERANGE */
Run Code Online (Sandbox Code Playgroud)

如果你需要解析其中带有"e"的数字(指数表示法),那么你应该使用strtod.当然,这些数字是浮点数,然后strtod返回double.如果要从中生成一个整数,可以在检查正确的范围后进行转换.


Mik*_*ike 7

你可以自己测试这种东西.我复制了Cplusplus参考站点的代码.看起来你对前两个例子的直觉是正确的,但第三个例子返回'0'.'E'和'e'被视为'B'也在第二个例子中.

所以规则是

成功时,该函数将转换后的整数作为int值返回.如果无法执行有效转换,则返回零值.如果正确的值超出可表示值的范围,则返回INT_MAX或INT_MIN.

  • -1.当输入无法表示为整数时,`atoi`的行为是未定义的,因此您无法自行测试; 任何调用未定义行为的测试都是无效的.Cplusplus.com并没有这么说,但[cplusplus.com是一个众所周知的不可靠的参考资料](http://stackoverflow.com/q/6520052/33732).你引用的是`strtol`的规则,但适用于`int`而不是`long`(这意味着它们根本不适用于任何函数).当您需要权威引用时,请使用该标准.如果需要快速参考,请使用cppreference.com. (3认同)

moo*_*dow 7

atoi从缓冲区读取数字,直到无法再读取为止。当它遇到任何非数字字符时,除了空格(它会跳过)或“+”或“-”之外,它会在看到任何数字(它用来为结果选择适当的符号)之前停止。 。如果没有看到数字,则返回 0。

因此,要回答您的具体问题: 1 返回 20234543。 2 返回 232。 3 返回 0。 字符“e”不是空格、数字、“+”或“-”,因此 atoi 在遇到该字符时会停止并返回。

另请参阅此处