So I have no idea why this behavior is observed:
#include <stdio.h>
int main()
{
unsigned char c;
char d;
scanf("%hhu", &d);
printf("%c\n", d);
return 0;
}
If I remember correctly %hhu
is for unsigned char
. If I input almost any character like a
, or b
the answer is nothing and d
gets the value 0
. But if I input 97
then d
prints the value a
(so ASCII is converted to char). This clearly not the case when the data type is char
. I can just input the character directly and it is stored.
Also in the slight modification of this code
#include <stdio.h>
int main()
{
unsigned char c;
char d;
int g;
scanf("%hhu", &d);
printf("%c\n", d);
scanf("%d", &g);
printf("%d is g\n", g);
return 0;
}
If I give first input as a character like w
or a
then it just skips the second scanf
, but if the input is a number then it works normally.
a
is not a valid input for %hhu
. An integer (in the Math sense) is expected. If we add error checking (code below), we get:
$ gcc -Wall -Wextra -pedantic a.c -o a && ./a
a
Number of assigned variables: 0
Can't read: Invalid input
#include <stdio.h>
#include <stdlib.h>
int main(void) {
unsigned char c;
int rv = scanf("%hhu", &c);
if (rv == EOF) {
if (ferror(stdin)) {
perror("Can't read");
} else {
fprintf(stderr, "Can't read: Premature EOF\n");
}
exit(1);
}
printf("Number of assigned variables: %d\n", rv);
if (rv < 1) {
fprintf(stderr, "Can't read: Invalid input\n");
exit(1);
}
printf("%hhu\n", c);
return 0;
}
Invalid input stays in the handle's buffer to be obtained by future reads. So an error in a early scanf
can cause later scanf
to fail.
If you wish to proceed after an error, you could simply read until you get a LF to clear any "junk" in the buffer.
void read_stdin_to_eol(void) {
while (1) {
int ch = getchar();
if (ch == '\n' || ch == EOF)
return ch;
}
}