C++ 字符串中的非整数数字并使用 atoi
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3214880/
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
Non-Integer numbers in an String and using atoi
提问by monksy
If there are non-number characters in a string and you call atoi [I'm assuming wtoi will do the same]. How will atoi treat the string?
如果字符串中有非数字字符并且您调用 atoi [我假设 wtoi 也会这样做]。atoi 将如何处理字符串?
Lets say for an example I have the following strings:
举个例子,我有以下字符串:
- "20234543"
- "232B"
- "B"
- “20234543”
- “232B”
- “乙”
I'm sure that 1 will return the integer 20234543. What I'm curious is if 2 will return "232." [Thats what I need to solve my problem]. Also 3 should not return a value. Are these beliefs false? Also... if 2 does act as I believe, how does it handle the e character at the end of the string? [Thats typically used in exponential notation]
我确定 1 会返回整数 20234543。我很好奇 2 是否会返回“232”。[这就是我需要解决的问题]。另外 3 不应返回值。这些信念是错误的吗?另外...如果 2 确实像我所相信的那样,它如何处理字符串末尾的 e 字符?[通常用于指数表示法]
回答by Alok Singhal
According to the standard, "The functions atof
, atoi
, atol
, and atoll
need not affect the value of the integer expression errno
on an error. If the value of the result cannot be represented, the behavior is undefined." (7.20.1, Numeric conversion functionsin C99).
根据标准,“函数atof
, atoi
, atol
, 和atoll
不需要影响整数表达式errno
错误时的值。如果结果的值无法表示,则行为未定义。” (7.20.1,C99 中的数字转换函数)。
So, technically, anything could happen. Even for the first case, since INT_MAX
is guaranteed to be at least 32767, and since 20234543 is greater than that, it could fail as well.
因此,从技术上讲,任何事情都可能发生。即使对于第一种情况,由于INT_MAX
保证至少为 32767,并且由于 20234543 大于此值,因此它也可能失败。
For better error checking, use strtol
:
为了更好地进行错误检查,请使用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 */
If you need to parse numbers with "e" in them (exponential notation), then you should use strtod
. Of course, such numbers are floating-point, and strtod
returns double
. If you want to make an integer out of it, you can do a conversion after checking for the correct range.
如果您需要解析其中包含“e”的数字(指数表示法),那么您应该使用strtod
. 当然,这些数字是浮点数,并strtod
返回double
。如果你想从中得到一个整数,你可以在检查正确的范围后进行转换。
回答by Mike
You can test this sort of thing yourself. I copied the code from the Cplusplusreference site. It looks like your intuition about the first two examples are correct, but the third example returns '0'. 'E' and 'e' are treated just like 'B' is in the second example also.
你可以自己测试这种事情。我从Cplusplus参考站点复制了代码。看起来您对前两个示例的直觉是正确的,但第三个示例返回 '0'。'E' 和 'e' 的处理方式与第二个示例中的 'B' 一样。
So the rules are
所以规则是
On success, the function returns the converted integral number as an int value. If no valid conversion could be performed, a zero value is returned. If the correct value is out of the range of representable values, INT_MAX or INT_MIN is returned.
成功时,该函数将转换后的整数作为 int 值返回。如果无法执行有效转换,则返回零值。如果正确值超出可表示值的范围,则返回 INT_MAX 或 INT_MIN。
回答by moonshadow
atoi
reads digits from the buffer until it can't any more. It stops when it encounters any character that isn't a digit, except whitespace (which it skips) or a '+' or a '-' before it has seen any digits (which it uses to select the appropriate sign for the result). It returns 0 if it saw no digits.
atoi
从缓冲区读取数字,直到不能再读取为止。当它遇到任何不是数字的字符时停止,除了空格(它跳过)或“+”或“-”,然后才能看到任何数字(它用于为结果选择适当的符号) . 如果没有看到数字,则返回 0。
So to answer your specific questions: 1 returns 20234543. 2 returns 232. 3 returns 0. The character 'e' is not whitespace, a digit, '+' or '-' so atoi stops and returns if it encounters that character.
因此,要回答您的具体问题:1 返回 20234543。2 返回 232。3 返回 0。字符 'e' 不是空格、数字、'+' 或 '-',因此 atoi 会在遇到该字符时停止并返回。
See also here.
另请参见此处。
回答by pcent
If atoi encounters a non-number character, it returns the number formed up until that point.
如果 atoi 遇到一个非数字字符,它会返回在该点之前形成的数字。
回答by J. Fernwright
I tried using atoi() in a project, but it wouldn't work if there were any non-digit characters in the mix and they came beforethe digit characters - it'll return zero. It seems to not mind if they come afterthe digits, for whatever reason.
我尝试在一个项目中使用 atoi() ,但如果混合中有任何非数字字符并且它们出现在数字字符之前,它将不起作用- 它会返回零。无论出于何种原因,它们是否出现在数字之后似乎都不介意。
Here's a pretty bare bones string to int converter I wrote up that doesn't seem to have that problem (bare bones in that it doesn't work with negative numbers and it doesn't incorporate any error handling, but it might be helpful in specific instances). Hopefully it might be helpful.
这是我写的一个非常简单的字符串到 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;
}
回答by dash-tom-bang
Writing simple code and looking to see what it does is magical and illuminating.
编写简单的代码并观察它的作用是神奇而富有启发性的。
On point #3, it won't return "nothing." It can't. It'll return something, but that something won't be useful to you.
在第 3 点上,它不会返回“什么都没有”。它不能。它会返回一些东西,但那些东西对你没有用。
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
http://www.cplusplus.com/reference/clibrary/cstdlib/atoi/
On success, the function returns the converted integral number as an int value.
If no valid conversion could be performed, a zero value is returned.
If the correct value is out of the range of representable values, INT_MAX or INT_MIN is returned.
成功时,该函数将转换后的整数作为 int 值返回。
如果无法执行有效转换,则返回零值。
如果正确值超出可表示值的范围,则返回 INT_MAX 或 INT_MIN。