[英]atoi() accepting strings mixed with number
For a task I need use if atoi(INPUT) == 0
to check that a users input is a valid integer and not 0. The problem is when I enter any string that starts with an integer, it is automatically accepted, even if there are non-integer characters after the integer, for example "1aaaabcc" is accepted.对于我需要使用
if atoi(INPUT) == 0
来检查用户输入是否有效的 integer 而不是 0 的任务。问题是当我输入任何以 integer 开头的字符串时,它会自动被接受,即使有是 integer 之后的非整数字符,例如接受“1aaaabcc”。
I understand that atoi() is in the example I just stated, would take the 1 and ignore it, but theortically this should be wrong input from the user since it is not a valid integer. Would there be something to add to my code (without adding any libraries) or change something with atoi to fix this?我知道 atoi() 在我刚才说的例子中,会取 1 并忽略它,但理论上这应该是用户输入的错误,因为它不是有效的 integer。我的代码中是否可以添加一些东西(不添加任何库)或用 atoi 改变一些东西来解决这个问题?
Please let me know if you need sample code in case its not clear.如果您需要示例代码以防不清楚,请告诉我。
The function atoi
is an "alias" for this function call function
atoi
是此 function 调用的“别名”
atoi: (int)strtol(nptr, (char **)NULL, 10)
So in your case you should use the function strtol
and pass the second argument unequal to NULL
that points to a pointer.因此,在您的情况下,您应该使用 function
strtol
并传递不等于指向指针的NULL
的第二个参数。 In this case you can check whether the pointer points to the end of the corresponding string.在这种情况下,您可以检查指针是否指向相应字符串的末尾。
Here is a demonstration program这是一个演示程序
#include <stdio.h>
#include <stdlib.h>
int main( void )
{
char *endptr;
int n = ( int )strtol( "A", &endptr, 10 );
printf( "n = %d, *endptr = %d\n", n, *endptr );
n = ( int )strtol( "10A", &endptr, 10 );
printf( "n = %d, *endptr = %d\n", n, *endptr );
n = ( int )strtol( "10", &endptr, 10 );
printf( "n = %d, *endptr = %d\n", n, *endptr );
}
Its output is它的 output 是
n = 0, *endptr = 65
n = 10, *endptr = 65
n = 10, *endptr = 0
As you can see only in the third call of the function strtol
the pointer endptr
points to the terminating zero character '\0'
.正如您只能在 function
strtol
的第三次调用中看到的那样,指针endptr
指向终止零字符'\0'
。 In all preceding calls it points to the letter 'A'
that has the ASCII code 65
.在所有前面的调用中,它指向具有 ASCII 代码
65
的字母'A'
。
You can also accept or deny strings like for example "10 "
.您还可以接受或拒绝字符串,例如
"10 "
。 If to accept such a string then in this case you need to check that the tail of the string contains only white space characters.如果要接受这样的字符串,那么在这种情况下,您需要检查字符串的尾部是否只包含空白字符。
You should attentively read the description of the function strtol
.您应该仔细阅读 function
strtol
的描述。
aoti()
is useful for quick and dirty code but not up to the task for robust error handling. aoti()
对于快速和肮脏的代码很有用,但不能胜任强大的错误处理任务。
Non-integer characters after the integer, as in "1aaaabcc"
is best detected with strtol()
. integer 之后的非整数字符,如
"1aaaabcc"
中的字符,最好使用strtol()
检测。
With strtol()
, we can detect more.使用
strtol()
,我们可以检测到更多。
Out of range for an int
like "12345678901234567890"
, but not the same length "00000000000000000001"
.超出了像
"12345678901234567890"
这样的int
的范围,但不是相同长度的"00000000000000000001"
。
Allow non-integer characters after the integer when text is all white-space.当文本全部为空白时,允许在 integer 之后使用非整数字符。 This is reasonable as
strtol()/atoi()
accept optional leading white-space.这是合理的,因为
strtol()/atoi()
接受可选的前导空白。 It also allows passing an entire line of input like "1234\n"
.它还允许传递整行输入,例如
"1234\n"
。
No conversion as in "asd"
, " "
, ""
.没有像
"asd"
、 " "
、 ""
那样的转换。
I recommend a helper function我推荐一个帮手 function
// Return true on success
bool convert_string_to_int(int *dest, const char *s) {
errno = 0;
char *endptr; // Gets updated to point to the end of the conversion.
long lvlaue = strtol(s, &endptr, 0);
if (s == endptr) {
*dest = 0;
return false; // No conversion
}
if (errno == ERANGE || lvalue < INT_MIN || lvalue > INT_MAX) {
errno = ERANGE;
*dest = lvalue < 0 ? INT_MIN : INT_MAX;
return false; // Out of range.
}
*dest = (int) lvalue;
if (errno) {
return false; // Implementation specific errors like s == NULL
}
while (isspace(*((unsigned char *)endptr))) {
endptr++;
}
if (*endptr) {
return false; // Junk at the end.
}
return true;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.