Originally Posted by
Elysia
Someone may want to write an article about clearing the input buffer. So common problem, yet I am too lazy to write one. Another thing to add to the list of someone interested.
So you want to clear an input buffer? "Clearing an input buffer" is a [[stupid|clever]] thing programmers will say instead of "ignoring some text." Chances are you are reading this because you've witnessed what happens if you don't ignore sufficiently. Data gets misplaced. Let's discuss fixes.
The smart thing to do is avoid the problem by storing each line of text completely. In C and C++ there is a newline character, '\n', that marks the end of the line. It doesn't matter if you're getting input from the keyboard or a file, you can depend on its presence: The last thing a user will do before the program works with the input is press enter, so you know the input is complete, even if it's malformed or bad input; files will have '\n' at the end of their lines. It looks like this in code:
Code:
/* C code: */
char section[BIGBUFF];
char *line = NULL;
while(fgets(section , BIGBUFF , stdin) != NULL) {
char *temp = NULL;
if(line != NULL) {
temp = realloc(line , strlen(line) + strlen(section) + 1);
}
else {
temp = realloc(line , strlen(section) + 1);
}
if(temp == NULL) /* plan to exit with error */ break;
line = temp;
strcat(line , section);
}
/* If there were no errors we can use the string data as an argument to sscanf,
or whatever you may need to do: */
if(ferror(stdin) == 0) {
parse(line);
}
This is the store everything, worry about validation later approach, a winning approach. This approach is also the one you should use for text files 99% of the time. Ignoring parts of input files can lead to [[garbage in, garbage out]] and all the misery that comes with it.
But perhaps you are a student and for one reason or another are not allowed to take it. You may be putting data directly into variables via cin or scanf, or getchar. You can still use what you know about '\n' to your advantage.
Code:
/* C code: */
int yourAge = 0;
char junk = '\0'
char first = 'A';
printf("What's your age?\n");
scanf("%d" , &yourAge);
while((junk = getchar()) != '\n' && junk != EOF);
printf("What's your first initial?\n");
first = getchar();
while((junk = getchar()) != '\n' && junk != EOF);
/* Example output:
What's your age?
42 abc\n
What's your first initial?
\n
*/
Consider the answer to the first question. We know that 42 is interesting. Scanf will read that into the variable good enough, but the other stuff ought to be ignored. If we follow the same strategy of reading until '\n' (in effect, the while loop above), we can pretty much guarantee a fresh read from the keyboard every time.
The answer to the second question introduces us to a problem with our handy loop. If the first = getchar(); statement accepts an '\n', our handy loop will wait for the person to type more! You've started a fresh read by accident. Unfortunately, there is not a lot you can do about this. If you stick to one function to read everything, you can avoid this, because you should either need to clean up after the same function every time, or never.
Consistency is what makes this work so well. For further reading, know how your file API functions work, and how they break, to make better input routines:
*[[Scanf woes]]
*[[fgets]]
*[[feof]]
Practice!