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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/14099473/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 04:55:35  来源:igfitidea点击:

How to scanf only integer and repeat reading if the user enters non-numeric characters?

cvalidationuser-input

提问by 7kemZmani

Here is some C code trying simply to prevent the user from typing a character or an integer less than 0 or more than 23.

下面是一些 C 代码,试图简单地防止用户输入字符或小于 0 或大于 23 的整数。

#include <stdio.h>
#include <stdlib.h>

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 != '
#include <stdio.h>  
#include <stdlib.h> 

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;  
}
') // 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; }

I made it halfway through and a small push up will be appreciated.

我做到了中途,一个小小的俯卧撑将不胜感激。

回答by MOHAMED

Use scanf("%d",&rows)instead of scanf("%s",input)

使用scanf("%d",&rows)代替scanf("%s",input)

This allow you to get direcly the integer value from stdin without need to convert to int.

这允许您直接从 stdin 获取整数值,而无需转换为 int。

If the user enter a string containing a non numeric characters then you have to clean your stdin before the next scanf("%d",&rows).

如果用户输入包含非数字字符的字符串,那么您必须在下一个scanf("%d",&rows).

your code could look like this:

您的代码可能如下所示:

scanf("%d%c", &rows, &c)

Explanation

解释

1)

1)

(scanf("%d%c", &rows, &c)!=2 || c!='\n')

This means expecting from the user input an integer and close to it a non numeric character.

这意味着期望用户输入一个整数并在其附近输入一个非数字字符。

Example1:If the user enter aaddkand then ENTER, the scanf will return 0. Nothing capted

示例 1:如果用户输入aaddkthenENTER,则 scanf 将返回 0。没有任何内容

Example2:If the user enter 45and then ENTER, the scanf will return 2 (2 elements are capted). Here %dis capting 45and %cis capting \n

示例 2:如果用户输入45然后ENTER,则 scanf 将返回 2(2 个元素被捕获)。这%d是捕获45%c捕获\n

Example3:If the user enter 45aaaddand then ENTER, the scanf will return 2 (2 elements are capted). Here %dis capting 45and %cis capting a

示例 3:如果用户输入45aaadd然后ENTER,则 scanf 将返回 2(2 个元素被捕获)。这%d是捕获45%c捕获a

2)

2)

((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())

In the example1:this condition is TRUEbecause scanf return 0(!=2)

在example1中:这个条件是TRUE因为scanf返回0(!=2)

In the example2:this condition is FALSEbecause scanf return 2and c == '\n'

在example2中:这个条件是FALSE因为scanf返回2并且c == '\n'

In the example3:this condition is TRUEbecause scanf return 2and c == 'a' (!='\n')

在example3中:这个条件是TRUE因为scanf返回2并且c == 'a' (!='\n')

3)

3)

#include <stdio.h>
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;
}

clean_stdin()is always TRUEbecause the function return always 1

clean_stdin()总是TRUE因为函数总是返回1

In the example1:The (scanf("%d%c", &rows, &c)!=2 || c!='\n')is TRUEso the condition after the &&should be checked so the clean_stdin()will be executed and the whole condition is TRUE

在例1:(scanf("%d%c", &rows, &c)!=2 || c!='\n')TRUE打完的情况&&,应检查,因此clean_stdin(),将被执行的整个条件是TRUE

In the example2:The (scanf("%d%c", &rows, &c)!=2 || c!='\n')is FALSEso the condition after the &&will not checked (because what ever its result is the whole condition will be FALSE) so the clean_stdin()will not be executed and the whole condition is FALSE

在示例 2 中:The(scanf("%d%c", &rows, &c)!=2 || c!='\n')isFALSEso the condition after the&&will not check(因为它的结果是整个条件将是FALSE)所以clean_stdin()不会被执行,整个条件是FALSE

In the example3:The (scanf("%d%c", &rows, &c)!=2 || c!='\n')is TRUEso the condition after the &&should be checked so the clean_stdin()will be executed and the whole condition is TRUE

在示例3:(scanf("%d%c", &rows, &c)!=2 || c!='\n')TRUE打完的情况&&,应检查,因此clean_stdin(),将被执行的整个条件是TRUE

So you can remark that clean_stdin()will be executed only if the user enter a string containing non numeric character.

所以你可以说clean_stdin()只有当用户输入一个包含非数字字符的字符串时才会执行。

And this condition ((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())will return FALSEonly if the user enter an integerand nothing else

只有当用户输入 an而没有其他内容时,此条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())才会返回FALSEinteger

And if the condition ((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())is FALSEand the integeris between and 1and 23then the whileloop will break else the whileloop will continue

如果条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())FALSE并且integer介于和之间123while循环将中断,否则while循环将继续

回答by Swathyprabhu

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

%[^0-9]in scanf()gobbles up all that is not between 0and 9. Basically it cleans the input stream of non-digits and puts it in str. Well, the length of non-digit sequence is limited to 100. The following %dselects only integers in the input stream and places it in num.

%[^0-9]scanf()狼吞虎咽所有不在0和之间的东西9。基本上它会清除非数字的输入流并将其放入str. 好吧,非数字序列的长度限制为100。以下%d仅选择输入流中的整数并将其放入num.

回答by Yonggoo Noh

int getInt()
{
  int n = 0;
  char buffer[128];
  fgets(buffer,sizeof(buffer),stdin);
  n = atoi(buffer); 
  return ( n > 23 || n < 1 ) ? 0 : n;
}

If the input is number, you can use fooas your input.

如果输入是数字,则可以foo用作输入。

回答by AndersK

You could create a function that reads an integer between 1 and 23 or returns 0 if non-int

您可以创建一个函数来读取 1 到 23 之间的整数,或者如果非整数则返回 0

e.g.

例如

##代码##

回答by Mats Petersson

You will need to repeat your call to strtolinside your loops where you are asking the user to try again. In fact, if you make the loop a do { ... } while(...);instead of while, you don't get a the same sort of repeat things twice behaviour.

您将需要strtol在您要求用户重试的循环内重复您的调用。事实上,如果你使循环 ado { ... } while(...);而不是 while,你不会得到相同类型的重复行为两次。

You should also format your code so that it's possible to see where the code is inside a loop and not.

您还应该格式化您的代码,以便可以看到代码在循环中的位置而不是。