2010-12-11 6 views
37

警告:私はこれを行う際のフォーマットではない文字列リテラルと私はこのコード行に乗る警告を削除したいフォーマット引数を持ちません

FILE *fil; 
char *imp; 
(...) 
fprintf(fil,imp); 

ことは、それが正確にファイルに書き込まれています私はしたいが、私はフォーマット%sのを適用した場合、技術的に文字列をprintfのような関数を呼び出すと間違って何もないものの、それは、この

fprintf(fil, "%s", imp); 
+0

'何が含まれてimp'のでしょうか? – casablanca

+1

fprintfを 'fputs(imp、fil);'に置き換えるとどうなりますか? – pmg

+0

文字列、このようなものを想定できます。imp = "test"; – Unzi

答えて

43

この警告は、printfスタイル関数(printf、fprintf ...など)に対する書式文字列引数を確認できないことを示すgccの方法です。この警告は、コンパイラが手動で文字列を覗き込むことができず、実行時に意図どおりにすべてが実行されることを保証できないときに生成されます。いくつかの例を見てみましょう。

ケース1は、この文字列は、コンパイル時に検証することができ、コンパイラは警告なしにそれを許可します:

printf("This string has no format"); 

ケース2:この場合、コンパイラはあなたが持っていることを検出することができます書式指定子を使用して別の警告を表示します。私のマシンでは、 "警告:フォーマットの引数が少なすぎる"と言っていました。

// This will most probably crash your machine 
printf("Not a safe string to %s"); 

ケース3.今、これはややあなたのケースです。実行時に生成された文字列を取得して印刷しようとしています。あなたが得ている警告は、文字列に書式指定子がある可能性があることを警告するコンパイラです。例えば ​​"bad%sdata"と言ってください。この場合、ランタイムは%sと一致する存在しない引数にアクセスしようとします。さらに悪いことに、これはユーザーがあなたのプログラムを悪用しようとしている可能性があります(読みにくいデータを読み込ませる)。

char str[200]; 
scanf("%s", str) 
printf(str) 
+0

'const char *'を期待し、 'char *'を与える関数を呼び出すと警告が出ないIMHO – terminus

+0

私は文字列がconstにキャストされることを提案していませんでした。私は、警告を修正するために2番目の引数を指定する必要があることに言及しました。 –

+0

"引数を指定する"必要があるのはどういう意味ですか? – UncleBens

14

のように、それはまだ悪い習慣でない文字列理由%sのようなフォーマットトークンを含むことができます。たとえばimp%s testの場合、悪いことが起こります。

書式設定なしでimpを印刷する場合は、fputs(imp, fil)(逆の引数に注意してください)を使用してください。

+8

さらに悪いことに、ユーザーがimp文字列を指定できる場合、彼はメモリを上書きするために%n形式トークンを使用できるかもしれません。これはフォーマット文字列攻撃と呼ばれ、注入されたコードを実行するために使用されます。 – ollb

+3

fputsは文字列sans%の書式を書き出すトリックを行います。 –

+0

"sans%formatting"とはどういう意味ですか? – TheRookierLearner

関連する問題