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

7ke*_*ani 13 c validation user-input

这是一个年轻的tyro问题,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 != '\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;  
}
Run Code Online (Sandbox Code Playgroud)

我做到了一半,一个小推高将被赞赏.

MOH*_*MED 35

scanf("%d",&rows)而不是scanf("%s",input)

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

如果用户输入包含非数字字符的字符串,则必须在下一个字符串之前清除stdin scanf("%d",&rows).

你的代码看起来像这样:

#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;  
}
Run Code Online (Sandbox Code Playgroud)

说明

1)

scanf("%d%c", &rows, &c)
Run Code Online (Sandbox Code Playgroud)

这意味着期望从用户输入一个整数并且接近它是非数字字符.

示例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')
Run Code Online (Sandbox Code Playgroud)

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

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

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

3)

((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())
Run Code Online (Sandbox Code Playgroud)

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

在例1:(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())才会返回FALSEinteger

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