printf ascii字符%有时给出c而不是%

printf ascii字符%有时给出c而不是%,c,ascii,printf,C,Ascii,Printf,对于printf如何处理ascii字符,我有点困惑 当我像这样打印字符%时,我会得到一个正确的响应,比如“ascii%”,这很好 printf("ascii %% \n"); printf("ascii \x25 \n"); printf("ascii %c \n", 0x25); ascii % 我可以像这样把它们放在同一行,得到“ascii%%”, 这也很好 printf("ascii %c \x25 \n", 0x25); ascii % % 但我不能按其他顺序做,因为我

对于printf如何处理ascii字符,我有点困惑

当我像这样打印字符%时,我会得到一个正确的响应,比如“ascii%”,这很好

printf("ascii %%   \n");
printf("ascii \x25 \n");
printf("ascii %c   \n", 0x25);

ascii % 
我可以像这样把它们放在同一行,得到“ascii%%”, 这也很好

printf("ascii %c \x25 \n", 0x25);

ascii % %
但我不能按其他顺序做,因为我得到的是c,而不是%,就像这个“ascii%c”

发生了什么事

但是我注意到printf似乎将\x25视为正常的%符号, 因为如果我在输出(\x25%)之后直接添加另一个%,它将成为我所期望的

printf("ascii \x25% %c \n", 0x25);

ascii % %
但后来我也注意到,打印一个百分比似乎也能起作用, 但我没想到会这样

printf("ascii %  \n");

ascii %
为什么这样做,我认为一个%不是printf的有效输入。。。 有人能澄清printf是如何工作的吗



注意:我在Ubuntu 12.04(gcc版本4.6.3)上使用默认的gcc。

是的,printf将\x25视为正常的%符号,
printf(“ascii%\n”)之所以有效,是因为
%
位于格式字符串的末尾(忽略空格)。

在C字符串语法中,转义字符
\
启动一个转义序列,编译器使用该转义序列生成将包含在最终二进制文件中的实际字符串。因此,在C源代码中,“%”和“\x25”将在最终二进制文件中生成完全相同的字符串

关于单个
%
,这是一个格式错误的字符串。它会导致未定义的行为。所以

printf("ascii \x25 %c \n", 0x25);
实际上与

printf("ascii % %c \n", 0x25);
它会导致未定义的行为。没什么可做的了,试图了解单百分比字符的情况是浪费时间。

格式
printf(“ascii\x25%c\n”,0x25),因为正如您猜测的那样\x25与“%”字符完全相同,所以它是{percent}{space}{percent}{c}。所以,它打印一个带有前导空格的百分号,然后是一个“c”

[编辑:如我所述,没有前导空格,因为'c'不是数字说明符]
[编辑2:参数“0x25”被忽略,因为没有匹配的说明符来使用它]

好问题!“ascii%\n”
“ascii%\n”
“警告:\x25%c”给出了“警告:转换在格式[-Wformat]末尾缺少类型”,但这与空格有关,因为“\x25%c”编译时没有任何警告。否。它与空间无关,至少不直接相关。实际上,当
printf
看到第一个
%
时,它开始解释格式化序列。空格可以在数字或字符串的格式序列中有效,因此可以接受该空格。但是,没有找到显示警告的其他格式字符(d、x、s…)。另一方面,当没有空间时,格式化序列只是由两个连续的百分比组成,因此是有效的。错误:
printf
从来看不到
\x25
。所以是预加载程序将\x25转换为%s,所以printf在运行时得到相同的输入?@Johan不,它不是预加载程序。编译器在可执行文件中生成相同的字符数组。实际上,他似乎忽略了中间的空间,因此它变成了{% }{%}{C},然后很清楚它将成为什么。是的,这就是我在第一次编辑中试图传达的,似乎不成功:^
printf("ascii % %c \n", 0x25);