DVerde
DVerde

Reputation: 27

fgets inside the while loop

I'm having an issue with fgets because it is returning \n on the first time it enters the while loop right after the k input. Since I'm already inside the while loop and my #1 try as already been written, how do I deal with this?

int main() {
    char r;

    printf("How to input?\n");
    printf("Keyboard ([K])\n File ([F])\n Leave ([E])\n");
    scanf("%c", &r);

    if (r == 'k' || r == 'K') {
        printf("\nKeyboard\n");
        opcaoTeclado();
    } else {
       // stuff
    }
}

void opcaoTeclado() {
    int try = 0;
    char inputline[161];

    while (try <= 10) {
        printf("\n#%d try\n ", try);
        fgets(inputline, 160, stdin);
        try++;
    }
}

Upvotes: 1

Views: 5313

Answers (4)

rootkea
rootkea

Reputation: 1484

  1. I'm having an issue with fgets because it is returning \n on the first time it enters the while loop right after the "k" input.

    That's because for scanf("%c", &r); when you enter k[ENTER_KEY], the character k gets stored in variable r leaving the \n (ENTER key pressed) in the stdin stream.

    So for fgets(inputline, 160, stdin);, it finds the \n newline character in stdin, stoes it in inputline and exits as from man -s3 fgets:

    fgets() reads in at most one less than size characters from stream and stores them into the buffer pointed to by s. Reading stops after an EOF or a newline. If a newline is read, it is stored into the buffer.


  1. Since I'm already inside the while loop and my "#1 try" as already been written, how do I deal with this?

    You can consume that \n in stdin by using getchar()

Upvotes: 1

LPs
LPs

Reputation: 16213

You could simply add as space after format to consume the \n

scanf("%c ", &r);

Upvotes: 1

P.P
P.P

Reputation: 121387

After the call to scanf(), there's a newline in the input which is read by the first call fgets(). fgets() stops reading input when it encounters a newline \n. Hence, it doesn't read any input.

Add a call to getchar(); right after scanf() to consume the newline.

Or you can also use a loop to consume if there are multiple chars in the input.

int c;

while((c= getchar()) != '\n' && c != EOF); 

In general, it's best to avoid mixing scanf() with fgets(). You can use fgets() instead of scanf() and parse the line using sscanf() which is less prone.

Upvotes: 4

V. Kravchenko
V. Kravchenko

Reputation: 1904

You should clean stdin's buffer. You can do it using fflush(stdin); before your loop. But it's a bad style. Consider also fseek(stdin,0,SEEK_END);.

Upvotes: 1

Related Questions