例如,假设我有以下字符串:
1. "20234543" 2. "232B" 3. "B"
我相信1将返回整数20234543。我想知道的是2是否会返回"232." [这就是我需要解决的问题]。另外,3不应返回值。这些看法是否错误?此外...如果2确实像我所认为的那样,它如何处理字符串末尾的e字符?[通常用于指数表示法]
根据标准,“函数atof
、atoi
、atol
和atoll
在出错时不需要影响整数表达式errno
的值。如果结果的值无法表示,则行为未定义。”(C99中的7.20.1,“数字转换函数”)。
因此,从技术上讲,任何事情都可能发生。即使是第一个 case,由于保证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
类型。如果您想将其转换为整数,则可以在检查正确范围后进行转换。
sizeof(int)>=4
。 - R.. GitHub STOP HELPING ICE0
是最方便的。这会自动将数字转换为常见的进制,特别是对于正常的十进制数,以及如果数字以0x
开头,则会从十六进制转换。 - Jens Gustedt因此,规则如下:
成功时,该函数将转换后的整数作为int值返回。 如果无法执行有效的转换,则返回零值。 如果正确的值超出可表示值的范围,则返回INT_MAX或INT_MIN。
atoi
函数在输入无法表示为整数时的行为是未定义的,因此您不能自行测试;任何调用未定义行为的测试都是无效的。cplusplus.com网站没有这样说,但cplusplus.com是一个臭名昭著的不可靠参考资料。您引用的是适用于long
的规则,但已经改编成适用于int
(这意味着它们实际上根本不适用于任何函数)。当您需要权威引用时,请使用标准。当您需要快速参考时,请使用cppreference.com。 - Rob Kennedyatoi
定义为具有与strtol
类似的行为,它处理前导空格(如果有),然后是数字,最后是任何未识别的字符(如果有)(http://pubs.opengroup.org/onlinepubs/009695399/functions/strtol.html)。在您的第二个示例中,`strtol`遇到了无法识别的字符并放弃了。 - gladedatoi
函数从缓冲区读取数字,直到无法继续为止。当它遇到任何不是数字的字符时停止,除了空格(它会跳过)或在看到任何数字之前的“+”或“-”符号(它用于选择结果的适当符号)。如果它没有看到任何数字,则返回0。
因此,回答您具体的问题:1返回20234543. 2返回232. 3返回0。“e”字符既不是空格,也不是数字、“+”或“-”,因此如果遇到该字符,atoi
函数将停止并返回。
另请参见这里。
我在一个项目中尝试使用atoi()函数,但是如果混合的字符串中有任何非数字字符并且它们出现在数字字符之前,该函数将返回零。不知道为什么,如果这些非数字字符出现在数字字符之后,该函数似乎并不介意。
下面是我编写的一个相当简单的字符串转整数转换器,它似乎没有这个问题(它不能处理负数,并且不包含任何错误处理,但在特定情况下可能会有所帮助)。希望它能有所帮助。
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;
}
当我学习编程时,我因为atoi函数的行为而责备自己。该函数通过启动命令行参数来计算整数阶乘结果的函数。
如果值不是数字,则atoi函数返回0,而“3asdf”返回3。正如我们所知道的那样,C语言将命令行输入参数处理为char数组指针变量。
有人告诉我,在书籍《Linux Hater's Handbook》中,有一些关于计算机极客并不喜欢atoi函数的讨论,因为它是愚蠢的,原因是没有办法检查给定输入类型的有效性。
有人问我为什么不使用位于stdlib.h库中的strtol函数,并为我的阶乘计算递归方法附上了一个示例,但我不在意阶乘结果是否超出了整数主类型值范围,超出了范围(太大的基数)。这将导致我的程序产生负值。
我通过首先检查给定用户输入参数是否真正是数字值,然后计算阶乘值来解决了我的问题。
使用位于chtype.h库中的isdigit()函数如下:
int checkInput(char *str[]) {
for (int x = 0; x < strlen(*str); ++x)
{
if (!isdigit(*str[x])) return 1;
}
return 0;
}
在另一个Linux编程论坛上,我的论坛朋友告诉我,如果我使用strtol,我可以处理超出范围的值或将有符号整数解析为无符号长类型,这意味着-0和其他负值不被接受。
重要的是,在我的代码中检查字符是否为数字值。检查这个的一种方式是当字符串中的第一个数字值出现时,函数返回失败结果进行协商(或在C中的字符数组中)。
atoi
在某些系统上的工作原理。 - Alok Singhalvoid
返回类型,这怎么可能呢? - Georg Fritzsche