Sahand
Sahand

Reputation: 8360

getchar function to clear input buffer outside of while-condition?

I have learned that one can empty the input buffer like this:

while((ch = getchar()) != EOF && ch != '\n');
if (ch == EOF) {
    // oops
}

Why then, can I not empty the buffer by one character with the line:

c = getchar();

This line will cause the program to wait for user input. Context:

void strfuncs()
{
    char name[50] = {0};
    char lastname[50] = {0};
    char c;

    printf("Enter name...:");
    fgets(name, 50, stdin);
    printf("Enter last name...:");
    fgets(lastname, 50, stdin);

    c=getchar();
    printf("Enter a character...:");
    fgets(&c, 1, stdin);

    printf("c: %c",c);
}

Upvotes: 0

Views: 1730

Answers (2)

ad absurdum
ad absurdum

Reputation: 21317

This idiom for emptying the input stream only works if there are characters in the input stream to be read; otherwise getchar() will block, waiting for input. If there are characters in the input stream, getchar() will read one of them.

The fgets() function keeps the newline character, so it may seem that it is not necessary to clean the input stream after getting a line of input this way. But, if the buffer is not large enough, there will be characters left behind. One way to handle this is to check the input buffer for a newline character, and clean the input stream if it is not present. If the newline is found in the input buffer, it is often removed:

char buffer[1000];

puts("Enter a line:");
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
    perror("Error in fgets()");
    exit(EXIT_FAILURE);
}

char *ch;
int c;
if ((ch = strchr(buffer, '\n')) == NULL) {
    while ((c = getchar()) != '\n' && c != EOF) {
        continue;
    }
} else {
    *ch = '\0';
}

Note that an int variable should be used to recieve the value returned by getchar(), to ensure that EOF is correctly handled.

Upvotes: 1

JeremyP
JeremyP

Reputation: 86651

c = getchar();

That does empty the buffer by one character, if there is a buffer. However, given the speed at which humans type relative to the speed at which computers operate, it is likely that the buffer is empty when that line gets executed. if the buffer is empty getchar will wait until it is not.

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

The above is no different. Most of the time, the computer will be waiting inside getchar for the buffer to become non empty.

In normal mode when standard input comes from the terminal, the operating system only sends characters to the program's input buffer when it has received a new line character or, if forced to by the user typing ctrl-D (on *nixes, not sure what the equivalent is on Windows). The loop will actually block in the first getchar() until you have typed a whole line and pressed return. It will then whizz round the loop as fast as possible consuming all the characters you typed. This all happens after you pressed the return key.

char c;        // <<<< Wrong!
c = getchar();

This is tangential to the question, but the type of getchar() is int. This is important because EOF needs to be differentiated from all of the valid characters that can be entered and in some character sets, every possible value of a char (0 to 255 or -128 to 127 on all modern common implementations) is a valid character.

Upvotes: 1

Related Questions