Guillaume Levesque
Guillaume Levesque

Reputation: 45

fgets() always waiting for input, can't find how to fix it

I have an issue here were I can't find a way to stop fgets() to read from stdin after I paste my input in it. I want it to read what I pasted and stop after (it can be different length). Now it is waiting for another input.

void readMatrix(char (*charM)[40]) {
    char charT[42] = {0};
    int count = 0;

    while (fgets(charT, 42, stdin) != NULL) {
        for (int i = 0; i < 40; i++){
            if (charT[i] == 0 || charT[0] == '\n' ) {
                printf("Erreur: Caractère `EOF` inattendu, attendu `H`, `X` 
ou `.`."); 
                exit(0);
            }
            if(charT[i] != '.' && charT[i] != 'H' && charT[i] != 'X') {
                printf("Erreur: Caractère `%c` inattendu, attendu `H`, `X` 
ou `.`.", charT[i]);
                exit(0);
            }
            charM[count][i] = charT[i];
        }
        count++;
        if (count == 20) break;
    }
}

Thanks!

Upvotes: 2

Views: 430

Answers (2)

Peter
Peter

Reputation: 36617

When you copy and paste, there is nothing copied that ends the input.

Since there is nothing copied in that ends the input, fgets() not return NULL.

After doing the copy and paste, there may be a last line of input waiting to be read. In that case, it is necessary to hit the enter key, so fgets() will return that last line of input. If you're lucky, that step is not necessary (because a carriage return has been copied as the last character) but there is still nothing telling fgets() that input has ended.

The fact that everything has been copied does not tell fgets() that input has ended. The significance is that, if you wish, you will be able to repeatedly copy text into your program, as many times as you like.

To actually signal the end of input to your program, you need to manually do something to indicate that. For most flavours of unix, that is done using CTRL-D. For windows, it is CTRL-Z. Depending on how your program is run (e.g. in a terminal window or not) it may be necessary to manually do that twice (e.g. hit CTRL-Z twice under windows).

Note that it is a good idea to hit the enter key at least once before signally end of input. If there is an incomplete line waiting to be read (i.e. no newline yet) some keyboard or terminal drivers will discard the last line if they encounter end of input. For example, under windows, always hit then CTRL-Z (and, possibly, you will still need to enter CTRL-Z a second time).

Note: some programs do sensibly handle copy and paste. But those programs use a system-dependent function INSTEAD of fgets() so they can recognise the end of copy/pasted text. You can't emulate that behaviour using fgets(), hence the need for the user to do something.

Upvotes: 1

Serkan Pek&#231;etin
Serkan Pek&#231;etin

Reputation: 693

while (fgets(charT, 42, stdin) != NULL)

Even though you do not type in anything and you hit enter, it will feed a null-terminated string in C. You either need to change this condition, or alternatively you need to feed the standard input an End-of-Transmission character. For Linux it is Ctrl + D, for Windows it is Ctrl + Z.

Upvotes: 3

Related Questions