的转换说明符中嵌入空字符

的转换说明符中嵌入空字符

本文介绍了为什么可以在 scanf 的转换说明符中嵌入空字符?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

也许我误解了我的结果,但是:

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 的转换说明符中嵌入空字符?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 09:15