che*_*shi 7 c printf c-strings undefined
我想知道如果我们打印内容中包含“%s”的字符串会是什么结果?
我尝试将其打印为“ hi%s”。
char *ptr="hi%s";
printf(ptr);
Run Code Online (Sandbox Code Playgroud)
我希望输出为“ hi”。但我以“嗨,嗨,%s”的名字得到它。
“嗨,嗨,%s”
Cab*_*ion 11
如在其他答案中指定的那样,将发生未定义的行为。
在这种情况下,未定义行为的含义是:
当printf接收到带有n个格式说明符(例如%s)的字符串时,除了该字符串之外,还期望将n个参数传递给该函数。因此,当您具有这样的语句时printf("hi%s"),该函数的行为就好像您传递了一个参数一样(在这种情况下,第二个参数应为char *),即使没有。该函数只是要获取堆栈中的下一个值,在这种情况下,这是一些垃圾值。然后,该函数将引用该垃圾值,并将其视为字符缓冲区。未定义此行为的原因是无法确定堆栈上的垃圾值是多少。
可能的结果
取消引用垃圾值时,堆栈上的垃圾值为0->分段错误。
堆栈上的垃圾值恰好是有效的内存地址->内存位置的字节将一直插入到字符串中(在这种情况下,附加到“ hi”),直到遇到值0的字节或分段为止发生故障。
产生相同的情况
下面的代码部分与以下情况非常相似printf("hi%s")
void foo() {
char * myJunkValue; // Since not a global/static variable, this is not guaranteed to be 0
printf(myJunkValue); // Undefined behavior
}
Run Code Online (Sandbox Code Playgroud)
您的程序调用未定义的行为。
您的代码等同于
printf("hi%s");
Run Code Online (Sandbox Code Playgroud)
在哪里%s是一个转换说明符,它期望提供一个参数。
引用C11第§7.21.6.1章
[...]如果格式的参数不足,则行为未定义。[....]
建议:如果只需要打印字符串,而无需任何转换(格式化),则可以使用puts()。
您不是在“打印包含%s其内容的字符串”。您正在将诸如格式字符串之类的字符串传递给printf,并且这样做没有格式字段的匹配参数,则您的程序具有未定义的行为。的第一个参数printf不是您要打印的字符串。这是一个格式字符串,它控制如何解释/转换其余参数,并且还可以包含将其合并到其中的文字文本。
可以通过或来完成“打印包含%s其内容的字符串”(ptr指向该字符串,如您的问题所示)。printf("%s", ptr)puts(ptr)