虽然使用scanf(),但为什么需要getchar()?

虽然使用scanf(),但为什么需要getchar()?,c,scanf,getchar,C,Scanf,Getchar,此代码应读取一个正数,如果用户输入一个非数字值,它将再次要求用户输入一个数字,并等待输入再次检查,直到输入一个数字 do { printf("Enter a positive number: "); } while ( (scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0) ) ; do { printf(“输入正数:”); } 而((scanf(“%d%c”,&n,&c)!=2 | | c!='\n'

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

 do
   {
        printf("Enter a positive number: ");
   }
  while ( (scanf("%d%c", &n,&c) != 2 || c!='\n' || n<0) ) ;
do
{
printf(“输入正数:”);
}
而((scanf(“%d%c”,&n,&c)!=2 | | c!='\n'| | n,因为大多数说明符的
scanf()
忽略了空格,如果
scanf()
保留在缓冲区中,则需要在再次调用
scanf()
之前收集它们。如果不收集它们(并立即丢弃它们),则
scanf()
将在下一次调用时立即返回。

因为大多数说明符的
scanf()
忽略了空格,如果
scanf()
仍保留在缓冲区中,则需要在再次调用
scanf()
之前收集它们。如果不收集它们(并立即丢弃),则
scanf()
将在下次通话时立即返回。

请参阅此代码

#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;
}
#包括
int
main(int argc,char*argv[]){
字符c=0;
scanf(“%c”、&c);
printf(“%c\n”,c);
scanf(“%c”、&c);
printf(“%c\n”,c);
返回0;
}
如果键入的字符超过两个或三个,则scanf的第二次调用不能作为中断调用。getch()不是标准的。此外,您不应该调用getchar(),因为它可能会阻塞。您可以使用fseek

使用fseek进行黑客攻击仅在Windows上有效:-(

糟糕的解决方案
#包括
int
main(int argc,char*argv[]){
字符c=0;
scanf(“%c”、&c);
printf(“%c\n”,c);
fseek(stdin,0,SEEK_END);
scanf(“%c”、&c);
printf(“%c\n”,c);
返回0;
}
好办法
#包括
int
main(int argc,char*argv[]){
char buf[BUFSIZ];
字符c=0;
scanf(“%c”、&c);
printf(“%c\n”,c);
而(!feof(stdin)&&getchar()!='\n');
scanf(“%c”、&c);
printf(“%c\n”,c);
返回0;
}
这在Windows和Linux上运行良好

请参阅此代码

#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;
}
#包括
int
main(int argc,char*argv[]){
字符c=0;
scanf(“%c”、&c);
printf(“%c\n”,c);
scanf(“%c”、&c);
printf(“%c\n”,c);
返回0;
}
如果键入的字符超过两个或三个,则scanf的第二次调用不能作为中断调用。getch()不是标准的。此外,您不应该调用getchar(),因为它可能会阻塞。您可以使用fseek

使用fseek进行黑客攻击仅在Windows上有效:-(

糟糕的解决方案
#包括
int
main(int argc,char*argv[]){
字符c=0;
scanf(“%c”、&c);
printf(“%c\n”,c);
fseek(stdin,0,SEEK_END);
scanf(“%c”、&c);
printf(“%c\n”,c);
返回0;
}
好办法
#包括
int
main(int argc,char*argv[]){
char buf[BUFSIZ];
字符c=0;
scanf(“%c”、&c);
printf(“%c\n”,c);
而(!feof(stdin)&&getchar()!='\n');
scanf(“%c”、&c);
printf(“%c\n”,c);
返回0;
}

这在Windows和Linux上运行良好

请考虑使用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);
char输入[40]=“”;
int valid=0;
int n=0;
做{
printf(“输入一个正整数\n”);
if(fgets(输入,sizeof(输入),标准输入)){
int last=0;
如果(1==(有效=sscanf(输入,“%d%n”、&n、&last))){
如果(n<0 | |输入[上次]!='\n'){
valid=0;//如果negative或last不是换行符,则重置
}
}
}
否则{
fprintf(stderr,“从fgets获取输入的问题”);
返回0;
}
}while(有效!=1);

考虑使用FGET收集输入。任何无效的输入都已从输入流中删除,以便于重试。
根据需要使用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);
char输入[40]=“”;
int valid=0;
int n=0;
做{
printf(“输入一个正整数\n”);
if(fgets(输入,sizeof(输入),标准输入)){
int last=0;
如果(1==(有效=sscanf(输入,“%d%n”、&n、&last))){
如果(n<0 | |输入[上次]!='\n'){
valid=0;//如果negative或last不是换行符,则重置
}
}
}
否则{
fprintf(stderr,“从fgets获取输入的问题”);
返回0;
}
}while(有效!=1);
scanf(“%d%c”…
遇到非数字输入时,
%d”
会导致扫描停止,并且在下一个输入函数中将有问题的字符保留在
stdin
中。
%c”
没有机会读取该非数字字符

如果代码使用相同的
scanf(“%d%c”…
)重新读取
stdin
,则结果相同。需要其他方法删除非数字输入。
getchar()
getch()
等将读取任意1个字符

scanf(“%d%c”)遇到非数字输入时,…
导致扫描停止,%d”
导致下一个输入函数的错误字符保留在
stdin
中。
%c”
没有机会读取该非数字字符

如果代码使用相同的
scanf(“%d%c”…
)重新读取
stdin
,则结果相同。需要其他方法删除非数字输入。
getchar()
getch()
等将读取任意1个字符


getch
不是标准格式,您的代码无论如何都不会使用它。虽然
%d
格式会清除输入缓冲区中的任何前导空格,但是当您输入say
123z
时,需要使用
clean\u stdin
来处理该情况。我使用fseek的原因是您可以使用CTRL-d来中断输入。因此您不能调用getchar()要等待“\n”。
getch
不是标准格式,您的代码无论如何都不会使用它。虽然
%d
格式会清除输入缓冲区中的任何前导空格,但是当您输入say
123z
时,需要使用
clean\u stdin
来处理该情况。我为什么使用fsee
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);