为什么我们需要getchar()虽然使用scanf()?

时间:2017-07-03 16:23:24

标签: c scanf getchar

此代码应读取正数,如果用户输入非数字值,则再次要求他输入数字并等待输入再次检查,直到输入数字

 do
   {
        printf("Enter a positive number: ");
   }
  while ( (scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0) ) ;

但实际上在输入非数字时它会继续执行while循环体,而不会等待检查while循环的条件while(scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0)

将条件编辑为

int clean_stdin()
{
    while (getchar()!='\n');
    return 1;
}

 do
   {
        printf("Enter a positive number: ");
   }
  while ( (scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0) && clean_stdin() ) ;

它以正确的方式执行,但我不明白为什么我们需要添加getchar(),尽管我们已经在条件中使用scanf()

4 个答案:

答案 0 :(得分:2)

考虑使用fgets收集输入。任何无效输入都已从输入流中删除,这使得再次尝试变得更加简单 根据需要使用sscanf或其他方法解析输入。

char input[40] = "";
int valid = 0;
int n = 0;

do {
    printf ( "Enter a positive integer\n");
    if ( fgets ( input, sizeof ( input), stdin)) {
        int last = 0;
        if ( 1 == ( valid = sscanf ( input, "%d%n", &n, &last))) {
            if ( n < 0  || input[last] != '\n') {
                valid = 0;//reset if negative or last is not newline
            }
        }
    }
    else {
        fprintf ( stderr, "problem getting input from fgets\n");
        return 0;
    }
} while ( valid != 1);

答案 1 :(得分:2)

scanf("%d%c", ...遇到非数字输入时,"%d"会导致扫描停止,并且违规字符将保留在stdin中以用于下一个输入功能。 "%c"没有机会阅读该非数字字符。

如果代码使用相同的stdin重新读取scanf("%d%c", ...,则结果相同。删除非数字输入需要一些其他方式。 getchar()getch()等会读取任意一个字符。

Example code GetPositiveNumber()

答案 2 :(得分:0)

因为具有大多数说明符的scanf()会忽略空格,并且如果缓冲区中遗留了scanf(),则需要在再次调用'\n'之前收集它们。如果你没有收集它们(并立即丢弃它们),那么scanf()将在下次通话时立即返回。

答案 3 :(得分:0)

请参阅此代码

#include <stdio.h>

int
main(int argc, char* argv[]) {
  char c = 0;
  scanf("%c", &c);
  printf("%c\n", c);
  scanf("%c", &c);
  printf("%c\n", c);
  return 0;
}

如果您键入两个或三个字符,则第二次调用scanf不会起到干扰。并且getch()不是标准的。你也不应该调用getchar(),因为它可能会阻塞。 您可以使用fseek

使用fseek的Hack只适用于Windows。 : - (

BAD SOLUTION

#include <stdio.h>

int
main(int argc, char* argv[]) {
  char c = 0;
  scanf("%c", &c);
  printf("%c\n", c);
  fseek(stdin, 0, SEEK_END);
  scanf("%c", &c);
  printf("%c\n", c);
  return 0;
}

良好的解决方案

#include <stdio.h>

int
main(int argc, char* argv[]) {
  char buf[BUFSIZ];
  char c = 0;
  scanf("%c", &c);
  printf("%c\n", c);
  while (!feof(stdin) && getchar() != '\n');
  scanf("%c", &c);
  printf("%c\n", c);
  return 0;
}

这适用于Windows&amp; Linux的