Background: When keys are typed, the ASCII (or extended-ASCII) codes associated with each key are sent to a place in memory called the keyboard buffer. Functions such as scanf() and getchar() read codes from this buffer NOT from the keyboard directly. This is because the actual codes (the scan codes) and the manner in which they are sent by the keyboard are very system specific and permit such things as distinguishing when a key is depressed and when it is released and whether the left shift key was pressed or the right shift key was pressed. Since ANSI C is intended to be platform independent, it is restricted to fetching input only from the keyboard buffer.
Behavior of getchar(): When getchar() is invoked, it goes and gets a single value from the keyboard buffer. If the buffer is empty, it waits (and hence your program waits) until the buffer is again loaded by the system this occurs when the return key is pressed by the user. As a result, getchar() cannot be used to detect and respond to a single key (other than return) being pressed by the user. Other functions, from non-ANSI compliant and system dependent libraries can.
However, there is a side effect of this behavior when the user types a key (say Y) and hits return, the call to getchar() returns Y (the ASCII code for the character Y) as desired. However, there is still a character in the keyboard buffer namely the ASCII code for the carriage return and this is the value that will be returned the next time that getchar() is called. Therefore, we must have a means of clearing out the keyboard buffer either before we ask the user to enter something or as a cleanup task after we get their input.
Experiment with the following code:
int main(void)
{
int answer;
answer = 0;
while('x' != answer)
{
answer = getchar();
printf("%i\n", answer);
}
return(1);
}
This will allow you to see what the code is that is returned as you enter various keys. You should notice that if you enter keys beyond what is contained in the ASCII character set such as the function keys or the control key with another key that the return value is generally meaningless. These keys are outside the ANSI C definition and therefore the behavior of getchar() when dealing with those key and/or key combinations is system dependent. More specifically, its dependent on what the hardware and/or operating system place in the keyboard buffer.
Answer the following question: What is the last code that is fetched from the buffer whenever you input valid ASCII-defined keys?
Now, try the following code:
int main(void)
{
int answer;
answer = 0;
while( ('Y' != answer) && ('N' != answer) )
{
printf("Enter your response: (Y/N)? ");
answer = getchar();
if( ('Y' != answer) && ('N' != answer) )
printf("Invalid Response - Please re-enter.\n");
}
printf(Thank you.\n);
return(0);
}
The goal of the above code is to exit the loop if the user enters a Y or an N and, if they dont, to issue the Invalid Response message and repeat the loop. But, while it basically accomplishes this, there are some annoying side effects. Can you tell where they come from? Try typing in a string of characters (that do not have either a Y or an N) instead of just one. Try typing a string of characters that has Y or N somewhere in the middle.
Keeping in mind the behavior and side effects of getchar() described above, modify the above code so that, if the FIRST character that the user enters at the prompt is NOT either a Y or a N (or the lowercase versions), the program will issue a single Invalid Response message. Hint the idea is to read the first character and then clear out the contents of the buffer with repeated calls to getchar().