我正在尝试从命令行中获取不带scanf()
但使用just 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);
......
首先,请记住,字符本质上不是字母字符;准确地说。
我认为您正在寻找的是“是整数”函数。在标准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] != '\0') {
if (isdigit(str[i++]) == 0) {
return -1;
}
}
return 0;
}
这是该函数的有效示例:https://onlinegdb.com/SJBdLdy78
正如评论者所说,请使用strtol()
而不是atoi()
。
strtol()
的问题在于,当转换后的数字不适合长型时,它只会给出ERANGE
错误(按照规范)。因此,如果您要求它转换" 1"
,则会得到1
。如果您要求它转换"apple"
,它将返回0
并将endptr
设置为错误。
很明显您需要确定" 12"
是否将成为可接受的输入-strtol()
会愉快地跳过前导空白。
EDIT:已更新功能,可以通过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;
}