11
#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...?

3lokh
  • 891
  • 4
  • 17
  • 39

5 Answers5

11

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
}
BLUEPIXY
  • 39,699
  • 7
  • 33
  • 70
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
        }
    }
pmg
  • 106,608
  • 13
  • 126
  • 198
  • 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`.) – chux - Reinstate Monica Aug 04 '16 at 14:50
  • 1
    @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. – pmg Aug 04 '16 at 15:31
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).

rustyx
  • 80,671
  • 25
  • 200
  • 267
  • The issue is like it will make the gets to wait when characters of length with in limit is entered.. – 3lokh Aug 04 '16 at 13:06
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
.
a3f
  • 8,517
  • 1
  • 41
  • 46
Gilbert
  • 3,740
  • 17
  • 19
  • 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. – chux - Reinstate Monica Aug 04 '16 at 14:54
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.

Tong Zhao
  • 91
  • 7