问题描述
也许我误解了我的结果,但是:
Perhaps I'm misinterpreting my results, but:
#include <stdio.h>
int
main(void)
{
char buf[32] = "";
int x;
x = scanf("%31[^\0]", buf);
printf("x = %d, buf=%s", x, buf);
}
$ printf 'foo\n\0bar' | ./a.out
x = 1, buf=foo
由于字符串文字 "%31[^\0]"
包含一个嵌入的 null,它似乎应该被视为与 "%31[^";
,编译器应该抱怨 [
不匹配.事实上,如果你替换字符串文字,clang 会给出:
Since the string literal "%31[^\0]"
contains an embedded null, it seems that it should be treated the same as "%31[^"
, and the compiler should complain that the [
is unmatched. Indeed, if you replace the string literal, clang gives:
警告:scanf 格式字符串 [-Wformat] 中的 '%[' 没有关闭 ']'
为什么在传递给 scanf 的字符串文字中嵌入空字符会起作用?
Why does it work to embed a null character in the string literal passed to scanf?
-- 编辑 --
以上是未定义的行为,只是碰巧工作".
The above is undefined behavior and merely happens to "work".
推荐答案
首先,Clang 完全无法输出这里有任何有意义的诊断,而 GCC 确切地知道发生了什么 - 所以再次 GCC 1- 0 叮当声.
First of all, Clang totally fails to output any meaningful diagnostics here, whereas GCC knows exactly what is happening - so yet again GCC 1 - 0 Clang.
至于格式字符串 - 好吧,它不起作用.scanf
的格式参数是一个字符串.该字符串以终止 null 结尾,即您提供给 scanf
的格式字符串是
And as for the format string - well, it doesn't work. The format argument to scanf
is a string. The string ends at terminating null, i.e. the format string you're giving to scanf
is
scanf("%31[^", buf);
在我的电脑上,编译程序给出
On my computer, compiling the program gives
% gcc scanf.c
scanf.c: In function ‘main’:
scanf.c:8:20: warning: no closing ‘]’ for ‘%[’ format [-Wformat=]
8 | x = scanf("%31[^\0]", buf);
| ^
scanf.c:8:21: warning: embedded ‘\0’ in format [-Wformat-contains-nul]
8 | x = scanf("%31[^\0]", buf);
| ^~
扫描集必须有右括号]
,否则转换说明符无效.如果转换说明符无效,则行为未定义.
The scanset must have the closing right bracket ]
, otherwise the conversion specifier is invalid. If conversion specifier is invalid, the behaviour is undefined.
而且,在我运行它的电脑上,
And, on my computer running it,
% printf 'foo\n\0bar' | ./a.out
x = 0, buf=
Q.E.D.
这篇关于为什么可以在 scanf 的转换说明符中嵌入空字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!