在C中执行fgets()后清除输入缓冲区

798qvoo8  于 2023-01-08  发布在  其他
关注(0)|答案(5)|浏览(186)
#include <stdio.h>
int main()
{
  char name[10];
  for(int i=0;i<=10;i++)
  {
    printf("Who are you? ");
    if(fgets(name,10,stdin)!=NULL)
    printf("Glad to meet you, %s.\n",name);
  }
  return(0);
}

当我输入超过10个字符时,循环跳过。

Who are you? aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa
Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaaaa.
Who are you? Glad to meet you, aaaaaaa

我想我想从剩余的字符中清除输入缓冲区。什么是最好的方法呢?

3htmauhk

3htmauhk1#

检查name中是否存在换行符。

#include <stdio.h>
#include <string.h>

int main(void){
    char name[10];

    for(int i=0;i<=10;i++){
        printf("Who are you? ");
        if(fgets(name,10,stdin)){
            char *p;
            if(p=strchr(name, '\n')){//check exist newline
                *p = 0;
            } else {
                scanf("%*[^\n]");scanf("%*c");//clear upto newline
            }
            printf("Glad to meet you, %s.\n", name);
        }
    }
    return(0);//Parentheses is not necessary
}
1aaf6o9v

1aaf6o9v2#

检查fgets()是否获得了'\n'。如果没有'\n',则当前行中的某些字符尚未读取。您可以简单地忽略它们。

printf("Who are you? ");
    if (fgets(name, 10, stdin) != NULL) {
        if (!strchr(name, '\n')) {
            // consume rest of chars up to '\n'
            int ch;
            while (((ch = getchar()) != EOF) && (ch != '\n')) /* void */;
            if (ch == EOF) /* input error */;
            printf("Glad to meet you, %s.\n", name);
        } else {
            printf("Glad to meet you, %s.", name); // name includes ENTER
        }
    }
to94eoyn

to94eoyn3#

来自fgets的文档(强调为我的):

  • 从流中读取字符并将其作为C字符串存储到str中,直到读取完(num-1)个字符或到达换行符或文件结尾,以先发生者为准.*

因此,您的输入(超出缓冲区)以9个字符(+1个空终止字符)的块读取。
您需要反复调用fgets,直到最后读取的字符是换行符(\n)。

mm9b1k5b

mm9b1k5b4#

您需要使用类似下面的代码来查找\n

/* flush unread input buffer */
while( ! strchr( name, '\n' ) )
    if( ! fgets(name,(sizeof name),stdin) )
        break;

注意:不确定这是一个bug还是一个特性,但是短名称将包含最后的\n

Glad to meet you SSS
.
zf2sa74q

zf2sa74q5#

使用strchr()判断stdin中是否有垃圾剩余,如果有,则使用getchar()、while循环和continue的常用组合来清理垃圾:

#include <stdio.h>
#include <string.h>
int main()
{
  char name[10];
  for(int i=0;i<=10;i++)
  {
    printf("Who are you? ");
    if(fgets(name,10,stdin)!=NULL){
        printf("Glad to meet you, %s.\n",name);
        /* If there is no '\n' in name, then there are garbage left in the stdin
            with a trailing '\n' */
        if ( strchr(name, '\n') == NULL )
            while (getchar() != '\n')
                continue;
    }
  }
  return(0);
}

并且输出:

Who are you? AAAAAAAAAA
Glad to meet you, AAAAAAAAA.
Who are you? bbbbbbbbbbbbbbbbbbbbbbb
Glad to meet you, bbbbbbbbb.
Who are you? ccccccccccccccccccccccccccc
Glad to meet you, ccccccccc.
Who are you? dddddddddddddddddddddddddddddd
Glad to meet you, ddddddddd.
Who are you? eeeeeeeeeeeeeeeeee
Glad to meet you, eeeeeeeee.
Who are you? fffffffffffffffffffff
Glad to meet you, fffffffff.
Who are you? ggggggggggggggggggggggggggg
Glad to meet you, ggggggggg.
Who are you? hhhhhhhhhhhhhhhhhhhhhhhhhhhhhh
Glad to meet you, hhhhhhhhh.
Who are you? iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii
Glad to meet you, iiiiiiiii.
Who are you? jjjjjjjjjjjjjjjjjjjjjjjjjj
Glad to meet you, jjjjjjjjj.
Who are you? kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk
Glad to meet you, kkkkkkkkk.

这确实是预期的行为。

相关问题