在以下情况下,%sign在printf语句中的作用

时间:2013-04-25 18:55:21

标签: c printf

我无法理解以下两种情况下的输出。 编译器:Windows上的Borland C ++ 5.02 案例1:

#include <stdio.h>

int main()
{
    char str[] = "HELLO";
    printf("%abc %2s", str, str);
    return 0;
}
output:%abc %2s

案例2:

#include <stdio.h>

int main()
{
    char str[] = "HELLO";
    printf("abc %2s", str, str);  //% sign removed
    return 0;
}
output:abc 1310540

请让我理解输出。如果它听起来很幼稚,请告诉我。我在C中很天真。

3 个答案:

答案 0 :(得分:3)

这是我的猜测:

printf("%abc %2s", str, str);

您的古代编译器会在%a格式字符串的引入之前提前发布。因此,运行时意识到它遇到了一个它无法识别的格式字符串,并放弃了尝试格式化。在任何情况下,您都无法将字符串传递给%a并期望任何有意义的内容。因此,即使您的编译器理解'%a',行为也将是未定义的。试图理解UB几乎没有什么可以获得的。修复你的代码。

printf("abc %2s", str, str);

应输出

abc HELLO
甚至在您的古老编译器上也是如此。如果没有,那就是编译器运行时的错误。

我个人准备打赌您的编译器会为该程序生成该输出。我宁愿想象你的问题被错误地转录了。问题中的输出与代码不匹配,反之亦然。

这是由你的pastebin确认的:

#include<stdio.h>

int main()
{
  char str[] = "HELLO";
    printf("abc %d", str, str);//different from code in question

    return 0;
}

Output: abc -1083086374

所以,不仅讨论UB有点无意义,当你运行的版本与问题中的代码不同时讨论程序更加毫无意义。将来,我建议您使用复制/粘贴将代码转换为Stack Overflow问题,然后进行双重和三重检查,确认输出是您声称的。

结论:现在是2013年。没有理由使用BCC v5.02。现在是时候向前迈进了。

答案 1 :(得分:0)

第一种是未定义的行为,因为您尝试将字符串打印为十六进制浮点。

第二个例子是有效的。它打印一个至少包含两个字符的字符串。忽略第二个参数str

答案 2 :(得分:0)

我不得不说你只需要阅读full POSIX documentation for printf(你也可以从Linux控制台输入man 3p printf)或者使用编译器/ C标准库实现的文档。

基本上,在%字符之后遇到的字符以非常特定的方式解释。 %后面的字符属于&#34;标记&#34;,&#34;长度修饰符&#34;和&#34;转换指定&#34; - 除转换说明符外,其中每个都是可选的。你的第二个例子应该给你一个警告,因为你有比你有转换说明符更多的值,它甚至看起来有一个bug,因为你不能使用数字标志(&#34; 2&#34;)和字符串转换说明符它吐出废话(可能是十进制的指针)。