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

时间:2010-07-09 17:00:13

标签: c++ c math atoi

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

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

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

7 个答案:

答案 0 :(得分:9)

根据标准,“函数atofatoiatolatoll不需要影响整数表达式errno的值错误。如果无法表示结果的值,则行为未定义。“ (7.99.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。如果你想从中产生一个整数,你可以在检查正确的范围后进行转换。

答案 1 :(得分:7)

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

所以规则是

  

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

答案 2 :(得分:3)

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

所以回答你的具体问题:1返回20234543. 2返回232. 3返回0.字符'e'不是空格,数字,'+'或' - '所以atoi停止并返回如果它遇到那个字符。

另见here

答案 3 :(得分:3)

如果atoi遇到一个非数字字符,它将返回在此之前形成的数字。

答案 4 :(得分: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;
}

答案 5 :(得分:0)

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

如果值不是数字值,atoi-function 返回 0,而 "3asdf" 返回 3。C 语言处理命令行输入参数,如我们都知道的 char -array 指针变量。

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

有些人问我为什么我不兄弟使用位于 stdlib.h -library 的 strtol 函数,他给了我一个附加到我的阶乘计算递归方法的示例,但我不在乎阶乘结果是否更大比整数主要类型值 - 范围,超出范围(基数太大)。它会在我的程序中产生负值。

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

使用位于 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,我可以处理值超出范围的情况,甚至可以将 signed int 解析为 unsigned long 类型,表示 -0 和其他负值不是接受。

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

答案 6 :(得分:-1)

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

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

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

  

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

     

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

     

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