I have the following code:
#include <stdio.h>
int main(void)
{
unsigned char c;
setbuf(stdin, NULL);
scanf("%2hhx", &c);
printf("%d\n", (int)c);
return 0;
}
I set stdin to be unbuffered, then ask scanf to read up to 2 hex characters. Indeed, scanf does as asked; for example, having compiled the code above as foo:
$ echo 23 | ./foo
35
However, if I strace the program, I find that libc actually read 3 characters. Here is a partial log from strace:
$ echo 234| strace ./foo
read(0, "2", 1) = 1
read(0, "3", 1) = 1
read(0, "4", 1) = 1
35 # prints the correct result
So sscanf is giving the expected result. However, this extra character being read is detectable, and it happens to break the communications protocol I am trying to implement (in my case, GDB remote debugging).
The man page for sscanf says about the field width:
Reading of characters stops either when this maximum is reached or when a nonmatching character is found, whichever happens first.
This seems a bit deceptive, at least; or is it in fact a bug? Is it too much to hope that with unbuffered stdin, scanf might read no more than the amount of input I asked for?
(I'm running on Ubuntu 18.04 with glibc 2.27; I've not tried this on other systems.)