如果用户输入非数字字符,如何仅扫描整数并重复读取?
这是一个年轻的tyro问题,C代码试图阻止用户输入一个小于0或大于23的字符或整数。
#include #include int main(void) { const char *input; char *iPtr; int count = 0; int rows; printf("Enter an integer: "); scanf("%s", input); rows = strtol(input, &iPtr, 0); while( *iPtr != '\0') // Check if any character has been inserted { printf("Enter an integer between 1 and 23: "); scanf("%s", input); } while(0 < rows && rows < 24) // check if the user input is within the boundaries { printf("Select an integer from 1 to 23: "); scanf("%s", input); } while (count != rows) { /* Do some stuff */ } return 0; }
我做到了一半,小小的推高将受到赞赏。
使用scanf("%d",&rows)
代替scanf("%s",input)
这允许您直接从stdin获取整数值,而无需转换为int。
如果用户输入包含非数字字符的字符串,则必须在下一个scanf("%d",&rows)
之前清理stdin。
你的代码看起来像这样:
#include #include int clean_stdin() { while (getchar()!='\n'); return 1; } int main(void) { int rows =0; char c; do { printf("\nEnter an integer from 1 to 23: "); } while (((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin()) || rows<1 || rows>23); return 0; }
说明
1)
scanf("%d%c", &rows, &c)
这意味着期望从用户输入一个整数并且接近它是非数字字符。
示例1:如果用户输入aaddk
然后ENTER
,则scanf将返回0.没有任何加盖
示例2:如果用户输入45
然后ENTER
,则scanf将返回2(2个元素被加上字符)。 这里%d
是上限45
, %c
是上限\n
示例3:如果用户输入45aaadd
然后ENTER
,则scanf将返回2(2个元素被加盖)。 这里%d
是上限45
, %c
是上限a
2)
(scanf("%d%c", &rows, &c)!=2 || c!='\n')
在example1中:此条件为TRUE
因为scanf返回0
( !=2
)
在示例2中:此条件为FALSE
因为scanf返回2
并且c == '\n'
在示例3中:此条件为TRUE
因为scanf返回2
并且c == 'a' (!='\n')
3)
((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
clean_stdin()
始终为TRUE
因为函数总是返回1
在example1中: (scanf("%d%c", &rows, &c)!=2 || c!='\n')
为TRUE
因此应检查&&
之后的条件,以便clean_stdin()
将是执行,整个条件为TRUE
在示例2中: (scanf("%d%c", &rows, &c)!=2 || c!='\n')
为FALSE
因此不会检查&&
之后的条件(因为它的结果是什么整个条件将为FALSE
)因此clean_stdin()
将不会被执行,整个条件为FALSE
在示例3中: (scanf("%d%c", &rows, &c)!=2 || c!='\n')
为TRUE
因此应检查&&
之后的条件,以便clean_stdin()
将是执行,整个条件为TRUE
所以你可以注意到,只有当用户输入一个包含非数字字符的字符串时才会执行clean_stdin()
。
并且这个条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
仅在用户输入integer
时才返回FALSE
如果条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
为FALSE
且integer
介于1
和23
之间,则while
循环将中断, while
循环将继续
#include main() { char str[100]; int num; while(1) { printf("Enter a number: "); scanf("%[^0-9]%d",str,&num); printf("You entered the number %d\n",num); } return 0; }
scanf()
%[^0-9]
吞噬了不在0
到9
之间的所有内容。 基本上它清理非数字的输入流并将其放入str
。 好吧,非数字序列的长度限制为100.以下%d
仅选择输入流中的整数并将其放在num
。
您可以创建一个读取1到23之间的整数的函数,如果是非int,则返回0
例如
int getInt() { int n = 0; char buffer[128]; fgets(buffer,sizeof(buffer),stdin); n = atoi(buffer); return ( n > 23 || n < 1 ) ? 0 : n; }
您需要在循环内重复调用strtol
,要求用户再次尝试。 事实上,如果你做循环a do { ... } while(...);
而不是同时,你没有得到同样的重复事情两次行为。
您还应该格式化代码,以便可以查看代码在循环内的位置而不是。
MOHAMED,你的答案很棒,这对我很有帮助。 在这里我发布了一个代码,我觉得它有点简单:
#include int getPositive(void); void clean_input(void); int main(void) { printf("%d\n",getPositive()); return 0; } int getPositive(void) { int number; char buffer; // Holds last character from user input. // (ie '\n' or any other character besides numbers) int flag; // Holds scanf return value do{ flag = scanf("%d%c", &number, &buffer); // Gets input from user // While scanf did not read 2 objects (ie 1 int & 1 char) // or the user inputed a number and then a character (eg. 12te) // ask user to type a valid value while (flag !=2 || buffer!='\n') { clean_input(); printf("%s","You have typed non numeric characters.\n" "Please type an integer\n?"); flag = scanf("%d%c", &number, &buffer); } if(number<0) { printf("%s","You have typed a non positive integer\n" "Please type a positive integer\n?"); } else { // If user typed a non negative value, exit do-while. break; } }while(1); } void clean_input(void) { while (getchar()!='\n'); return; }
在我的情况下,我希望数字只是积极的。 如果您希望数字介于1和23之间,则将number<0
替换为number<1 || number>23
if语句中的number<1 || number>23
。 此外,您还必须更改printf
以打印相应的消息。
char check1[10], check2[10]; int foo; do{ printf(">> "); scanf(" %s", check1); foo = strtol(check1, NULL, 10); // convert the string to decimal number sprintf(check2, "%d", foo); // re-convert "foo" to string for comparison } while (!(strcmp(check1, check2) == 0 && 0 < foo && foo < 24)); // repeat if the input is not number
如果输入是数字,则可以使用foo
作为输入。