C中的格式说明符 - %s内的%s

时间:2012-04-24 11:15:54

标签: c format-specifiers

我有类似的东西

char string[]="My name is %s";

printf("%s",string,"Tom");

我希望输出为My name is Tom,但我得到My name is %s

我尝试转义%字符,但它有效。

这里出了什么问题?如何在%s内加%s

5 个答案:

答案 0 :(得分:7)

尝试这样的事情

printf(string,"Tom");

你方法的问题是这个 -

只要printf在格式字符串中看到%s格式说明符,就会假定列表中的下一个参数是字符指针指向的字符串,检索它并将其打印出来代替%s。现在,printf不执行递归替换 你%s内的string保持不变,“汤姆”现在是一个额外的参数,只是被丢弃了。

答案 1 :(得分:3)

printf期间只有一次扩张;这意味着传递给printf的任何字符串除了格式字符串将逐字打印(如果有的话)。这实际上是一件好事,因为否则会留下巨大的安全漏洞。

安全风险涉及格式字符串和参数列表必须对应的事实。这意味着,如果不需要的%使其成为格式字符串,您将遇到麻烦:

char ch[50];
fgets(ch, 50, stdin);
printf(ch);

如果用户提供例如。 %p %p %p %p,他将读取存储在堆栈中的数据(如返回地址等),如果他提供%s %s %s,他可能会崩溃该程序。如果他提供%n,他将覆盖堆栈中的一些数据。

那就是说,你可以根据需要计算格式字符串:

char ch[50];
char format_prototype[]="My name is %s";
snprintf(ch, 49, "%s", format_prototype);
ch[49]=0;
printf(ch, "Tom");

答案 2 :(得分:1)

也许是{p> printf(string, "Tom")

答案 3 :(得分:1)

printf的第一个参数是格式字符串。其余的都是将根据格式字符串格式化的参数。格式字符串不以任何方式嵌套。换句话说,即使要格式化的字符串恰好包含格式化指令,也只是打印它而不是解释为另一种格式字符串。

如果你想拥有那种格式化间接,你必须先生成一个新的格式字符串(sprintf对此有用):

char string[] = "My name is %s";
char format[100];

sprintf(format, "%s", string);

然后使用新生成的格式字符串:

printf(format, "Tom");

答案 4 :(得分:1)

问题在于printf("%s",string,"Tom"); 行 你应该使用

char string[]="My name is %s";
printf(string,"Tom");

这里你将获得输出

My name is Tom