如果用户输入非数字字符,如何仅扫描整数并重复读取?

这是一个年轻的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())FALSEinteger介于123之间,则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]吞噬了不在09之间的所有内容。 基本上它清理非数字的输入流并将其放入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作为输入。