仅使用 fgets 检查整数而不检查字符串
Checking just integers and no strings using fgets only
我试图在没有 scanf()
的情况下从命令行获取一个整数,但仅使用 fgets()
,如果我插入一个字符,我如何过滤 fgets() contents
报告错误还是一个字符串?问题是,当我插入不同的东西时,如字符或字符串,atoi()
函数(在我的算法中执行某些操作所必需的)将我将该字符串转换为 0,而如果插入的值我更愿意退出不同于整数。
这是代码部分:
.....
char pos[30];
printf("\n Insert a number: ");
fgets (pos, sizeof(pos), stdin);
if (atoi(pos) < 0) //missing check for string character
exit(1);
else{
printf ("%d\n", atoi(pos)); //a string or character converted through atoi() gives 0
}
int number = atoi(pos);
......
首先,您必须记住字符本质上不是字母字符;准确一点。
我认为您要查找的是 "is integer" 函数。
在标准 C 库 ctype.h
中有函数称为 isalpha
和 isdigit
.
https://www.programiz.com/c-programming/library-function/ctype.h/isalpha
所以你可以创建一个函数来验证 char *
是否只包含数字字符。
int str_is_only_numeric(const char *str) {
int i = 0;
while (str[i] != '[=10=]') {
if (isdigit(str[i++]) == 0) {
return -1;
}
}
return 0;
}
下面是该函数的一个工作示例:https://onlinegdb.com/SJBdLdy78
正如评论者所说,使用 strtol()
而不是 atoi()
。
strtol()
的问题在于,当转换后的数字不适合 long 类型时,它只会给出 ERANGE
错误(根据规范)。因此,如果您要求它转换 " 1"
,它会给出 1
。如果您要求它转换 "apple"
,它会 returns 0
并设置 endptr
以指示错误。
显然 你 需要决定 " 12"
是否是可接受的输入 — strtol()
会愉快地跳过前导白色 space.
编辑:功能已更新,可通过 endptr
.
更好地处理错误
// Convert the given <text> string to a decimal long, in <value>
// Allow a string of digits, or white space then digits
// returns 1 for OK, or 0 otherwise
int parseLong( const char *text, long *value )
{
int rc = 0; // fail
char *endptr; // used to determine failure
if ( text && value )
{
errno = 0; // Clear any errors
*value = strtol( text, &endptr, 10 ); // Do the conversion
// Check that conversion was performed, and
// that the value fits in a long
if ( endptr != text && errno != ERANGE )
{
rc = 1; // success
}
}
return rc;
}
在检查 isdigit()
整数类型之前,我使用 strcspn()
自己解决了,没有 strcspn() 它总是返回 -1
我试图在没有 scanf()
的情况下从命令行获取一个整数,但仅使用 fgets()
,如果我插入一个字符,我如何过滤 fgets() contents
报告错误还是一个字符串?问题是,当我插入不同的东西时,如字符或字符串,atoi()
函数(在我的算法中执行某些操作所必需的)将我将该字符串转换为 0,而如果插入的值我更愿意退出不同于整数。
这是代码部分:
.....
char pos[30];
printf("\n Insert a number: ");
fgets (pos, sizeof(pos), stdin);
if (atoi(pos) < 0) //missing check for string character
exit(1);
else{
printf ("%d\n", atoi(pos)); //a string or character converted through atoi() gives 0
}
int number = atoi(pos);
......
首先,您必须记住字符本质上不是字母字符;准确一点。
我认为您要查找的是 "is integer" 函数。
在标准 C 库 ctype.h
中有函数称为 isalpha
和 isdigit
.
https://www.programiz.com/c-programming/library-function/ctype.h/isalpha
所以你可以创建一个函数来验证 char *
是否只包含数字字符。
int str_is_only_numeric(const char *str) {
int i = 0;
while (str[i] != '[=10=]') {
if (isdigit(str[i++]) == 0) {
return -1;
}
}
return 0;
}
下面是该函数的一个工作示例:https://onlinegdb.com/SJBdLdy78
正如评论者所说,使用 strtol()
而不是 atoi()
。
strtol()
的问题在于,当转换后的数字不适合 long 类型时,它只会给出 ERANGE
错误(根据规范)。因此,如果您要求它转换 " 1"
,它会给出 1
。如果您要求它转换 "apple"
,它会 returns 0
并设置 endptr
以指示错误。
显然 你 需要决定 " 12"
是否是可接受的输入 — strtol()
会愉快地跳过前导白色 space.
编辑:功能已更新,可通过 endptr
.
// Convert the given <text> string to a decimal long, in <value>
// Allow a string of digits, or white space then digits
// returns 1 for OK, or 0 otherwise
int parseLong( const char *text, long *value )
{
int rc = 0; // fail
char *endptr; // used to determine failure
if ( text && value )
{
errno = 0; // Clear any errors
*value = strtol( text, &endptr, 10 ); // Do the conversion
// Check that conversion was performed, and
// that the value fits in a long
if ( endptr != text && errno != ERANGE )
{
rc = 1; // success
}
}
return rc;
}
在检查 isdigit()
整数类型之前,我使用 strcspn()
自己解决了,没有 strcspn() 它总是返回 -1