Search code examples
cstdinfgets

fgets from stdin with unpredictable input size


I'm trying to read a line from stdin but I don't know to properly handle the cases when input size is at least equal to the limit. Example code:

void myfun() {
    char buf[5];
    char somethingElse;

    printf("\nInsert string (max 4 characters): ");
    fgets (buf, 5, stdin);

    ...

    printf("\nInsert char: ");
    somethingElse = getchar();
}

Now, the user can do three things:

  1. Input less than 4 characters (plus newline): in this case there's nothing left in stdin and the subsequent getchar() correctly waits for user input;
  2. Input exactly 4 characters (plus newline): in this case there's a newline left in stdin and the subsequent getchar() reads it;
  3. Input more than 4 characters (plus newline): in this case there's at least another character left in stdin and the subsequent getchar() reads it, leaving at least a newline in.

Cases 2 and 3 would require emptying stdin using something like while(getchar() != '\n'), whereas case 1 doesn't require any additional action. As I understand from reading answers to similar questions and c-faq, there's no standard/portable way to know whether the actual scenario is the one described in 1 or not.

Did I get it well? Or there actually is a portable way to do it? Or maybe a totally different approach?


Solution

  • The fgets function will store the newline in the buffer if there is room for it. So if the last character in the string is not a newline, you know you need to flush the buffer.

    fgets (buf, 5, stdin);
    if (strrchr(buf, '\n') == NULL) {
        // flush buffer
        int c;
        while ((c = getchar()) != '\n') && (c != EOF));
    }