As per the C FAQ: http://c-faq.com/stdio/scanfprobs.html
We should not use scanf for interactive input output, but instead we should resort to reading the whole line with fgets and then try to parse it with sscanf, prompting the user to type input again if sscanf returns parsing errors.
This, IIUC, would lead to code like this:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main()
{
char inpbuff[5];
signed char n;
bool read_correctly = false;
while(!read_correctly) {
printf("Please enter an 8bit number: ");
if(fgets(inpbuff, sizeof(inpbuff), stdin) == NULL)
return EXIT_FAILURE;
if(sscanf(inpbuff, "%hhd", &n) == 1)
read_correctly = true;
}
printf("You have entered: %hhd\n", n);
return EXIT_SUCCESS;
}
For me this approach creates problems if the user types a line that is longer than the size of the buffer provided for fgets. Even in the program above problems start to occur if the user types in asdf or asdf14.
In such a case we should, ideally, ignore all characters until we see a '\n', ignore this \n and only then again ask the user to provide their input. This would lead to an approach like this:
#include <stdio.h>
#include <stdbool.h>
#include <stdlib.h>
int main()
{
char inpbuff[5];
signed char n;
bool read_correctly = false;
while(!read_correctly) {
printf("Please enter an 8bit number: ");
switch(scanf("%hhd", &n)) {
case 1:
read_correctly = true;
break;
case 0: {
char sink;
do {
sink = fgetc(stdin);
if(sink == EOF)
return EXIT_FAILURE;
} while(sink != '\n');
break;
}
default:
return EXIT_FAILURE;
}
}
printf("You have entered: %hhd\n", n);
return EXIT_SUCCESS;
}
Which I suppose must be suboptimal since it is contrary to what the C FAQ recommends! And I definitely do not consider myself wiser than the C FAQ authors.
So, how does a typical processing of interactive input/output in C look like?
mallocto create a buffer. If you don't see a\nin thefgetsinput buffer you can reallocate it and repeat until you do. Your phrase resort to reading the whole line withfgetssuggests you are reluctant to go there.char inpbuff[500];case 0: { char sink;should have beencase 0: { int sink;to correctly distinguish anEOFfrom one of the 256 characters.