例如,我想有@Nonnegative,定义为@Min(0),并@DaySeconds定义为@Min(0) @Max(86399).
我有以下代码:
#include <stdio.h>
int main(void)
{
unsigned char c;
setbuf(stdin, NULL);
scanf("%2hhx", &c);
printf("%d\n", (int)c);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
我设置stdin为无缓冲,然后要求scanf读取最多 2 个十六进制字符。确实,scanf按要求做;例如,将上面的代码编译为foo:
$ echo 23 | ./foo
35
Run Code Online (Sandbox Code Playgroud)
但是,如果我strace编写程序,我发现 libc 实际上读取了 3 个字符。这是来自 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
Run Code Online (Sandbox Code Playgroud)
所以 sscanf 给出了预期的结果。但是,正在读取的这个额外字符是可以检测到的,它碰巧破坏了我试图实现的通信协议(在我的例子中是 GDB 远程调试)。
sscanf 的手册页说明了字段宽度:
当达到此最大值或找到不匹配的字符时(以先发生者为准),字符读取停止。
至少,这似乎有点欺骗性;或者它实际上是一个错误?希望使用无缓冲的标准输入,scanf 可能读取的输入量不会超过我要求的输入量,这是否太过分了? …