scanf()
関数の戻り値が浮動小数点数かどうかを確認したい。どうやってやるの?関数に間違ったデータ型が指定されていると、コードが正常に実行されませんscanf()
。同様に、返された値が文字列かどうかを確認するにはどうすればよいですか?
2 に答える
scanf()
et al は、成功した変換の数を返します。
あなたが持っている場合:
scanf("%f", &f);
テストする必要があります:
if (scanf("%f", &f) == 1)
...all OK...
else
...EOF or conversion failure...
複数の変換がある場合は、それらがすべて完了したことを確認してください。「コンバージョン」を使用している場合%n
、それらはカウントされません。
scanf()
EOF で EOF を返しますが、それをテストするべきではありません — 主に、期待した数の変換が得られたことを常に確認する必要があります。たとえば、バグのあるコードを考えてみましょう:
while (scanf("%f %d %s", &f, &i, s) != EOF) // Here be BUGS!
...loop body...
と入力すると、最初の反復で 1 が返され (3.14 が正常に変換された)、その後は 0 が返される (EOF ではない)3.14 x23 yes
ため、無限ループが発生します。scanf()
あなたは大丈夫かもしれません:
while ((rc = scanf("%f %d %s", &f, &i, s)) != EOF)
{
if (rc != 3)
...oops data problems...
else
...all OK...
}
以前の質問から判断すると、fgets()
(またはおそらく POSIX getline()
) を使用してデータ行を読み取り、次にsscanf()
またはのような関数を使用して、行から特定の値を読み取るstrtol()
ことを検討する必要があります。strtod()
を使用する場合sscanf()
、成功した変換の数の確認に関する上記のコメントが引き続き適用されます。
scanf()
プロダクション コードでは使用しません。適切に制御するのは非常に困難です。プログラムを始めるのにほぼ適していると思いますが、多くの混乱を招くことを除けば. 全体として、最善のアドバイスは「scanf()
とを避ける」ことfscanf()
です。を避ける必要があるという意味ではありませんが、 を使用するsscanf()
場合でも注意が必要ですsscanf()
。
の戻り値はscanf
、正常に読み取られ、変数または EOF に割り当てられたアイテムの数を示します。
これらの関数は、正常に一致して割り当てられた入力項目の数を返します。これは、提供された数より少ないか、初期の一致に失敗した場合はゼロになることもあります。
最初の変換の成功または一致の失敗が発生する前に入力の終わりに達した場合、値 EOF が返されます。読み取りエラーが発生した場合にも EOF が返されます。この場合、ストリームのエラー インジケータ (ferror(3) を参照) が設定され、エラーを示す errno が設定されます。
によってint
返されscanf
た値が、フォーマット文字列の入力指定子 (または少なくとも引数を渡す必要がある指定子) の量よりも少ない場合、何か問題が発生したと見なすことができます。
ただし、浮動小数点数のより完全な検証を実行する場合は、 の使用を検討する必要がありますstrtod()
。すなわち。input の"1.23abc"
場合、変数にscanf
保存1.23
され、すべてがうまくいったことstrtod
がわかりますが、最後に変換された文字が実際に解析されている文字列の末尾であるかどうかを確認できます。