当printf没有给出格式说明符时会发生什么?

时间:2014-01-26 22:52:03

标签: c string

我在关于printf的职业生涯中遇到过这个问题。

char *str = "hello";
printf("%s",str);
printf(str);

第二个printf语句有时会崩溃。我检查了各种网站。写了程序,看看它是否确实如此。但事实并非如此。另外,我知道printf接受类型为“const char * format”的参数,但格式可以是任何常量字符串,如“hello”。但是,如果我将它存储在字符串str(它指向只读存储器)中。预计它的工作方式相同。究竟发生了什么?

有人可以给出详尽的解释。

3 个答案:

答案 0 :(得分:2)

格式字符串中的格式说明符不是必需的,所以:

printf("%s", "Hello world\n");

printf("Hello world\n");

会产生相同的行为。

但是如果字符串在:

printf(str);

来自用户输入,你应该使用%s说明符,否则你很容易格式化字符串攻击(攻击者可以用%x伪造字符串来转储堆栈,%n到覆盖记忆)。

答案 1 :(得分:1)

使用动态格式字符串调用printf通常不是安全

void foo(char const * p)
{
    printf(p);   // !
}

单独从程序源代码中无法判断程序是否正确。正确性取决于字符串的(即它不能包含格式说明符),并且可能是未定义的行为。

这是该语言的一个不安全方面:您放弃了类型系统(因为变量参数),因此您放弃了静态正确性可验证性。

按字面意思打印字符串的安全方法可能是fputs(p, stdout),或者(效率较低)printf("%s", p)

答案 2 :(得分:0)

char *str = "hello";
printf(str);

相当于:

printf("hello");

就像:

char *format = "%s",
     *str = "hello";
printf(format, str);

相当于:

char *str = "hello";
printf("%s",str);

......你是否能真正依赖format的内容是完全不同的故事。