Yusuf Jama
Yusuf Jama

Reputation: 123

Cleaning stdin buffer issue

Say I have the following piece of code

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

int main() {
    char choice;
    char name[5] = "";
    do {
        printf("a = new name or anything else to quit\nChoice: ");
        choice = getchar();
        //not doing any error handling....assuming you only click 'a'
        switch (choice) {
            case 'a':
                getchar();
                printf("Enter a name which is 4 characters or less: ");
                fgets(name, 5, stdin);
                printf("Name: %s\n", name);
                char c;
                while ((c = getchar()) != '\n' && c != EOF);
                printf("%c", c);
                c = '\0';
                break;
            default:
                break;
        }

    } while (choice == 'a');
    printf("Ending.....press enter now");
    getchar();
    return 0;
}

What I am try to test here is clearing buffer when I have more than 4 characters typed into. It works fine whenever I have a name which is 4 chars or more, however when I hit 3 chars or less, the problem becomes the while loop. It expects a getchar() from the stdin buffer, however this is empty. What way is there to work around this issue?

Upvotes: 0

Views: 310

Answers (3)

chux
chux

Reputation: 154169

  1. Check the result of fgets(). Unless code does so, using the contents of name may be undefined behavior. Avoid magic numbers: uses sizeof name.

            // fgets(name, 5, stdin);
            if (fgets(name, sizeof name, stdin) == NULL) Handle_EOF();
    
  2. Look for a potential '\n' in name[].

            char *eol = strchr(name, '\n');
    
  3. If one is found, overwrite with the null character, else consume the rest of the line

            if (eol) {
              *eol = '\0';
            } else {
              int ch;
              while ((ch = getchar()) != '\n' && ch != EOF);
            }
    
  4. Print name[]

            printf("Name: %s\n", name);
    

Upvotes: 0

dbush
dbush

Reputation: 224927

You need to check if name contains a newline character. If it does, there's nothing in the buffer and you don't need to flush it.

    fgets(name, 5, stdin);
    printf("Name: %s\n", name);
    if (strchr(name, '\n') == NULL) {
        int c;
        while ((c = getchar()) != '\n' && c != EOF);
    }

Upvotes: 1

John Bollinger
John Bollinger

Reputation: 181199

We already discussed this in passing in the commentary on my answer to your previous question. If there is room for it in the buffer, fgets() will consume the terminating newline, placing it in the buffer. You can determine whether it has done so by looking for a newline in the buffer. If you find one, then

  1. You probably want to remove it -- by replacing it with '\0', for example.

  2. You should avoid trying to drain the tail of the input line, because the stream has already advanced to the next line.

Upvotes: 1

Related Questions