内部が私は出力がMy name is Tom
ことを期待し、この書式指定子 - %sの%sの
char string[]="My name is %s";
printf("%s",string,"Tom");
のようなものを持っているが、私は%
文字をエスケープしようとしたMy name is %s
を取得していますが、それdint work。
ここで何が問題になりますか? %s
内にはどのように%s
がありますか?
内部が私は出力がMy name is Tom
ことを期待し、この書式指定子 - %sの%sの
char string[]="My name is %s";
printf("%s",string,"Tom");
のようなものを持っているが、私は%
文字をエスケープしようとしたMy name is %s
を取得していますが、それdint work。
ここで何が問題になりますか? %s
内にはどのように%s
がありますか?
あなたの方法に問題がこれである。この
printf(string,"Tom");
のようなものを試してみてください - とすぐprintf
があなたのフォーマット文字列で%s
書式指定子を見て、それはリストの次の引数がAであることを前提として
文字ポインタが指す文字列を取り出し、%s
の代わりにそれを取り出して出力します。今度はprintf
はの再帰的なの置き換えを行わないので、string
の中には %s
が残っており、 "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);
ユーザー用品などの場合。%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");
+1のセキュリティ面を議論する –
printfのはわずか%を解釈します。 – nos