scanf字段宽度字符串溢出

jim*_*mis 7 c input scanf

关于缓冲区溢出,以下哪一项是安全的?

char buf[10] = {0};
scanf("%10s", buf);
Run Code Online (Sandbox Code Playgroud)

要么

char buf[10] = {0};
scanf("%9s", buf);
Run Code Online (Sandbox Code Playgroud)

从我读过的内容来看,我要去的是第二个(sizeof减去一个),但问题非常微妙,而且我已经看到了代码建议.有志于引用标准的志愿者吗?

hda*_*nte 13

C标准规定:

输入项应定义为输入字节的最长序列(直到任何指定的最大字段宽度,可以用字符或字节来衡量,取决于转换说明符),它是匹配序列的初始子序列.

也就是说,最大字段宽度表示输入中可以有多少个字符.最后的额外零值不是输入的一部分,需要额外的空间.

GNU libc的手册说明了这一点明确:

字符串输入转换存储空字符以标记输入的结尾; 最大字段宽度不包括此终止符.

所以,唯一安全的版本是scanf("%9s", buf).