Очистить входной буфер после fgets() в C

#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

Наверное, я хочу очистить входной буфер от оставшихся символов. Каков будет лучший способ сделать это...?

5 ответов

Решение

Проверить наличие новой строки в 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
}

Проверить, если 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
        }
    }

Из документации для fgets(выделение мое):

Считывает символы из потока и сохраняет их в виде строки C в строке str до тех пор, пока не будет прочитано (num-1) символов, либо не будет достигнут перевод строки или конец файла, взависимости от того, что произойдет раньше.

Таким образом, ваш ввод (который превышает буфер) читается в блоках по 9 символов (+1 символ с нулевым символом в конце).

Вам нужно позвонить fgets до тех пор, пока последний прочитанный символ не будет новой строкой (\n).

Вам нужно искать \n используя что-то вроде следующего:

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

Примечание: не уверен, если вы считаете это ошибкой или функцией, но короткие имена будут включать в себя окончательный \n, Это приводит к чему-то вроде:

Glad to meet you SSS
.

Использоватьstrchr()чтобы определить, есть ли остатки мусора вstdin, затем используйте обычно используемую комбинациюgetchar(), а цикл и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.

что действительно является предполагаемым поведением.

Другие вопросы по тегам