Clear input buffer after fgets() in C
Asked Answered
C

5

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

When I input something greater than 10 characters the loop skips.

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

I guess I want to clear the input buffer from the remaining characters. What will be the best way to do that...?

Conformation answered 4/8, 2016 at 12:55 Comment(0)
V
12

check exist newline in 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
}
Variometer answered 4/8, 2016 at 13:9 Comment(1)
Good use of scanf("%*[^\n]");scanf("%*c"); rather than the incorrect scanf("%*[^\n]%*c");Parolee
T
4

Check if fgets() obtained a '\n'. If there is no '\n', some characters in the current line haven't been read. You can simply just ignore them.

    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
        }
    }
Translation answered 4/8, 2016 at 13:39 Comment(2)
Unclear why if (ch == EOF) is considered an error as it could simple be that stdin was closed. (e. g. re-directed input: program_foo < input.txt.)Parolee
@chux: you can check ferror() and/or feof() to make sure. For me a line includes the ENTER. If the last character in a file is not a '\n', that file terminates with something other than a line.Translation
Z
1

From the documentation for fgets (emphasis mine):

Reads characters from stream and stores them as a C string into str until (num-1) characters have been read or either a newline or the end-of-file is reached, whichever happens first.

So your input (which exceeds the buffer) is read in blocks of 9 chars (+1 null-terminating char).

You need to call fgets repeatedly until the last read character is a newline (\n).

Zephyr answered 4/8, 2016 at 13:0 Comment(1)
The issue is like it will make the gets to wait when characters of length with in limit is entered..Conformation
C
1

You need to look for a \n using something like the following:

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

Note: not sure if you consider this a bug or a feature, but short names will include the final \n. This results in something like:

Glad to meet you SSS
.
Circumferential answered 4/8, 2016 at 13:25 Comment(1)
This is a good idea, except the extra calls of fgets() would be better to (IMO), use a different buffer than name[]. OTOH @Nikhil George is not clear on name[] contents in this situation.Parolee
S
0

Use strchr() to determine if there is garbage leftover in stdin, then use a commonly used combination of getchar(), while loop and continue to clean up the garbage if it is the case:

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

And the output:

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.

which is the intended behavior indeed.

Shrimp answered 4/1, 2023 at 21:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.