如何只整数SCANF和重复,如果用户输入非数字字符阅读?(How to scanf only int

2019-07-17 17:45发布

这里是一个小青年初学者与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;  
}

我做到了一半和一个小的推升将不胜感激。

Answer 1:

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

这允许你从标准输入获得direcly整数值,而不需要转换为int。

如果用户输入包含非数字字符,那么你必须清理下一个之前,你的标准输入一个字符串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;  
}

说明

1)

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

这意味着来自用户输入期望的整数,靠近它的非数字字符。

例1:如果用户输入aaddk然后ENTER ,scanf函数将返回0没有capted

例2:如果用户输入45 ,然后ENTER ,scanf函数将返回2(2个元件capted)。 这里%d被capting 45%c是capting \n

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

2)

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

在例1:此条件为TRUE因为scanf函数返回0!=2

在例2:该条件是FALSE因为scanf函数返回2c == '\n'

在示例3:此条件为TRUE因为scanf函数返回2c == 'a' (!='\n')

3)

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

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())将返回FALSE仅当用户输入一个integer ,没有别的

如果条件((scanf("%d%c", &rows, &c)!=2 || c!='\n') && clean_stdin())FALSEinteger之间和123 ,则while循环将打破别人的while循环将继续



Answer 2:

#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;
}

%[^0-9]scanf()吃掉所有不在之间09 。 基本上它清除的非数字的输入流,并把它在str 。 那么,非数字序列的长度被限制为100以下的%d仅选择输入流并将其放置在在整数num



Answer 3:

你可以创建一个函数读取整数1和23或回报之间0,如果非INT

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


Answer 4:

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作为输入。



Answer 5:

您将需要重复您的来电strtol您的循环中,你都要求用户再次尝试。 事实上,如果你让一个循环do { ... } while(...); 而不是同时的,你没有得到一个相同的排序重复两次东西的行为。

你也应该格式化你的代码,以便有可能看到的代码是一个循环中,而不是。



Answer 6:

MOHAMED,你的答案是伟大的,它真的帮了我。 在这里,我已经发布了代码,我认为这是一个有点简单:

#include <stdio.h>

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. 
                  // (i.e '\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 (i.e 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<0number<1 || number>23 number<1 || number>23 if语句。 你也将有改变printf打印相应的消息。



文章来源: How to scanf only integer and repeat reading if the user enter non numeric characters?