5

如果字符串中有非数字字符并且您调用 atoi [我假设 wtoi 也会这样做]。atoi 将如何处理字符串?

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

  1. “20234543”
  2. “232B”
  3. “乙”

我确定 1 会返回整数 20234543。我很好奇 2 是否会返回“232”。[这就是我需要解决我的问题]。3也不应该返回一个值。这些信念是错误的吗?另外...如果 2 确实像我相信的那样行事,它如何处理字符串末尾的 e 字符?[通常以指数表示法使用]

4

7 回答 7

10

根据标准,“函数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 */

如果您需要解析其中带有“e”的数字(指数符号),那么您应该使用strtod. 当然,这样的数字是浮点数,并且strtod返回double. 如果你想从中得到一个整数,你可以在检查正确的范围后进行转换。

于 2010-07-09T17:10:54.093 回答
10

你可以自己测试这种东西。我从Cplusplus参考站点复制了代码。看起来您对前两个示例的直觉是正确的,但第三个示例返回“0”。'E' 和 'e' 的处理方式与第二个示例中的 'B' 一样。

所以规则是

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

于 2010-07-09T17:05:50.443 回答
5

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

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

另请参见此处

于 2010-07-09T17:06:30.457 回答
3

如果 atoi 遇到非数字字符,它将返回直到该点形成的数字。

于 2010-07-09T17:09:14.287 回答
0

当我在学习接近编码程序时,我将自己归咎于这种 atoi 函数行为,该程序通过启动命令行参数来计算给定输入参数的整数阶乘结果。

如果 value 不是数字值,则 atoi-function 返回 0 并且“3asdf”返回 3。众所周知,C 语言处理 char -array 指针变量中的命令行输入参数。

有人告诉我,在“Linux Hater's Handbook”一书中,有一些吸引计算机极客的讨论并不真正喜欢 atoi 函数,因为无法检查给定输入类型的有效性,这有点愚蠢。

有人问我为什么不兄弟使用位于 stdlib.h -library 上的 strtol -function,他给了我一个附加到我的阶乘计算递归方法的示例,但我不关心阶乘结果大于整数主类型值-范围,超出范围(基数太大)。这将导致我的程序中出现负值。

我用 atoi-function 解决了我的问题,首先检查给定用户的输入参数是否是真正的数值,如果匹配,然后我计算阶乘值。

使用位于 chtype.h -library 上的 isdigit() -函数如下:

int checkInput(char *str[]) {
 for (int x = 0; x < strlen(*str); ++x)
    {
        if (!isdigit(*str[x])) return 1;
    }
    return 0;
}

我在其他 Linux 编程论坛中的论坛朋友告诉我,如果我使用 strtol,我可以处理超出范围值的情况,甚至可以将带符号的 int 解析为 unsigned long 类型,意思是 -0 并且不接受其他负值。

如果字符不是数值,则在我的代码检查中很重要。检查这个的协商方式,当第一个数值出现在检查字符串旁边时,函数返回失败的结果。(或 C 中的 char 数组)

于 2021-02-13T13:48:27.123 回答
0

我尝试在项目中使用 atoi() ,但如果混合中有任何非数字字符并且它们出现在数字字符之前,它将不起作用- 它会返回零。似乎不介意它们是否出现数字之后,无论出于何种原因。

这是我写的一个非常简单的字符串到 int 转换器,它似乎没有这个问题(简单的骨头,它不适用于负数并且它不包含任何错误处理,但它可能有助于具体实例)。希望它可能会有所帮助。

int stringToInt(std::string newIntString)
{
    unsigned int dataElement = 0;
    unsigned int i = 0;

    while ( i < newIntString.length())
    {
        if (newIntString[i]>=48 && newIntString[i]<=57)
        {
         dataElement += static_cast<unsigned int>(newIntString[i]-'0')*(pow(10,newIntString.length()-(i+1)));
        }
        i++;
    }
    return dataElement;
}
于 2018-10-09T20:40:24.220 回答
-1

编写简单的代码并查看它的作用是神奇而富有启发性的。

在第 3 点,它不会返回“无”。它不能。它会返回一些东西,但这些东西对你没有用。

http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/

成功时,函数将转换后的整数作为 int 值返回。

如果无法执行有效转换,则返回零值。

如果正确值超出可表示值的范围,则返回 INT_MAX 或 INT_MIN。

于 2010-07-09T17:04:26.967 回答