他の人に使用を勧めず、もっと良い選択肢があると言う人を頻繁に見かけますscanf
。しかし、結局私が目にするのは「使用しないでくださいscanf
」または「正しいフォーマット文字列は次のとおりです」、そして、「より良い代替案」言及された。
たとえば、次のコード スニペットを見てみましょう。
scanf("%c", &c);
これは、最後の変換後に入力ストリームに残された空白を読み取ります。通常、これに対する推奨される解決策は、次のとおりです。
scanf(" %c", &c);
または使用しないことscanf
。
は良くないので、を使用せずに通常は処理できる入力形式 (整数、浮動小数点数、文字列など) をscanf
変換するための ANSI C オプションにはどのようなものがありますか?scanf
scanf
ベストアンサー1
入力を読み取る最も一般的な方法は次のとおりです。
fgets
通常提案されているように、固定サイズで使用し、を使用します
fgetc
。これは、 1 つの だけを読み取る場合に便利ですchar
。
入力を変換するには、さまざまな関数を使用できます。
strtoll
文字列を整数に変換するstrtof
//d
、ld
文字列を浮動小数点数に変換するsscanf
、これはとして単に を使用するのと同じくらい悪いですscanf
が、以下に述べる欠点のほとんどがあります。ANSI Cで区切り文字で区切られた入力を解析する良い方法はありません。POSIX
strtok_r
のまたは を使用してくださいstrtok
。これはスレッドセーフではありません。自分で巻くおよび を使用するスレッドセーフなバリアントstrcspn
ではstrspn
、strtok_r
特別な OS サポートは必要ありません。やり過ぎかもしれませんが、レクサーとパーサー (最も一般的な例) を使用でき
flex
ますbison
。変換は不要、単に文字列を使用するだけ
詳しくは説明しなかったがなぜ scanf
私の質問は良くないので、詳しく説明します。
変換指定子
%[...]
とを使用すると%c
、scanf
空白文字を消費しません。これはあまり知られていないようです。この質問。の引数 (特に文字列)
&
を参照するときに単項演算子を使用するタイミングについては、多少の混乱があります。scanf
からの戻り値を無視するのは非常に簡単です
scanf
。これにより、初期化されていない変数を読み取ることで未定義の動作が簡単に発生する可能性があります。でのバッファオーバーフローを防止することを忘れることは非常に簡単です
scanf
。scanf("%s", str)
は、 と同じくらい、あるいはそれ以上に悪いですgets
。整数を で変換する場合、オーバーフローを検出することはできません
scanf
。実際、オーバーフローは未定義の動作これらの機能では。