web-dev-qa-db-ja.com

警告:文字列リテラルではなく、フォーマット引数なしでフォーマットしてください

このコード行に表示される警告を削除したいのですが、

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

事は私がこれを行うとき、それは私が望むものをファイルに正確に書き込みますが、私がこのようにフォーマット%sを適用する場合はそうではありません

fprintf(fil, "%s", imp);
43
Unzi

この警告は、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)
50
Sanjit Saluja

技術的には、文字列でprintfのような関数を呼び出すことに何の問題もありませんが、文字列には_%s_のようなフォーマットトークンが含まれている可能性があるため、依然として悪い習慣です。たとえば、impが_%s test_の場合、悪いことが起こります。

impをフォーマットせずに印刷したい場合は、fputs(imp, fil)を使用する必要があります(逆の引数に注意してください)。

17
terminus