简体   繁体   English

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

[英]What happens when a format specifier is not given to printf?

I came across this question in careercup about printf. 我在事业生涯中遇到有关printf的问题。

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

Second printf statement sometimes crash. 第二个printf语句有时会崩溃。 I checked on various sites. 我检查了各个站点。 Wrote the program to see if it actually does. 编写程序以查看是否确实如此。 But it does not. 但事实并非如此。 Also, I know that printf accepts an argument of type "const char* format" but format can be any constant string like "hello". 另外,我知道printf接受类型为“ const char * format”的参数,但是format可以是任何常量字符串,例如“ hello”。 But if I store it in a string str (which is ofcourse pointing to read-only memory). 但是,如果我将其存储在字符串str中(这当然指向只读内存)。 It is expected to work the same way. 有望以相同的方式工作。 What exactly happens? 到底发生了什么?

Can someone give a thorough explanation. 有人可以提供详尽的解释。

Format specifiers in the format string are not required so: 不需要格式字符串中的格式说明符,因此:

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

and

printf("Hello world\n");

will produce the same behavior. 会产生相同的行为。

However if the string in: 但是,如果字符串在:

printf(str);

comes from an user input, you should use the %s specifier otherwise you are prone to format string attacks (the attacker could forge strings with %x to dump the stack and %n to overwrite memory). 来自用户输入,应使用%s说明符,否则您很容易格式化字符串攻击(攻击者可以伪造具有%x字符串以转储堆栈,而%n伪造字符串以覆盖内存)。

It is generally not safe to call printf with a dynamic format string: 用动态格式字符串调用printf通常是不安全的

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

You cannot tell from the program source code alone whether the program is correct. 您不能仅从程序源代码中判断程序是否正确。 The correctness depends on the value of the string (ie it must not contain format specifiers), and it may be undefined behaviour. 正确性取决于字符串的 (即,它不能包含格式说明符),并且它可能是未定义的行为。

This is one of the unsafe aspects of the language: you are abandoning the type system (because of the variable arguments), and so you abandon static correctness verifiability. 这是该语言的不安全方面之一:您正在放弃类型系统(由于变量参数),因此您放弃了静态正确性可验证性。

The safe way to print a string literally would be either fputs(p, stdout) , or (less efficiently perhaps) printf("%s", p) . 从字面上看,打印字符串的安全方法是fputs(p, stdout)或(可能效率不高) printf("%s", p)

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

is equivalent to: 等效于:

printf("hello");

Just like: 就像:

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

is equivalent to: 等效于:

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

... and whether you can truly rely on the content of format or not is completely different story. ...以及您是否可以真正依赖format的内容完全不同。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM