里面我有这样的事情格式符 - %s%S
char string[]="My name is %s";
printf("%s",string,"Tom");
我希望可以将输出为My name is Tom
但我正在逐渐My name is %s
我试图逃避%
字符,但它辛苦工作。
这里怎么回事?如何在%s
内有%s
?
里面我有这样的事情格式符 - %s%S
char string[]="My name is %s";
printf("%s",string,"Tom");
我希望可以将输出为My name is Tom
但我正在逐渐My name is %s
我试图逃避%
字符,但它辛苦工作。
这里怎么回事?如何在%s
内有%s
?
尝试这样的事情
printf(string,"Tom");
与方法的问题是这样的 -
只要printf
看到%s
格式说明您的格式字符串,它假定在列表中的下一个参数是一个由字符指针指向的字符串,检索它并在%s
的位置打印它。现在,printf
不会执行递归替换,因此 %s
在您的string
中保持原样,“Tom”现在是一个额外的参数,它只是被丢弃。
printf(string, "Tom")
也许?
printf
的第一个参数是格式字符串。其余的都是根据格式字符串格式化的参数。格式字符串不以任何方式嵌套。换句话说,即使要格式化的字符串恰好包含格式化指令,它也可以简单地打印出来,而不会被解释为另一种格式字符串。
如果你想有那种格式化间接的,你必须首先生成一个新的格式字符串(sprintf
是有用):
char string[] = "My name is %s";
char format[100];
sprintf(format, "%s", string);
,然后用新生成的格式字符串:
printf(format, "Tom");
问题是与printf("%s",string,"Tom");
线 您应该使用
char string[]="My name is %s";
printf(string,"Tom");
在这里你会得到输出
My name is Tom
有在printf
只有一个扩展;这意味着任何字符串传递给printf
,格式字符串将逐字打印(如果有的话)。这实际上是一件好事,否则会留下巨大的安全漏洞。
安全风险与格式字符串和参数列表必须对应的事实有关。这意味着,如果不想要%
使得它的格式字符串,你会遇到麻烦:
char ch[50];
fgets(ch, 50, stdin);
printf(ch);
如果用户提供如。如果他提供%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");
+1讨论安全方面 – 2012-04-24 11:34:27
的printf只在它的第一个参数,格式字符串解释%。 – nos 2012-04-24 11:20:53