裏面我有這樣的事情格式符 - %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