私の実験では、この表現
double d = strtod("3ex", &end);
で初期化d
し、入力文字列内の文字にポインターを3.0
置きます。これはまさに私が期待する動作と同じです。文字は指数部の先頭に見えるかもしれませんが、実際の指数値 (6.4.4.2 で必要) がないため、完全に独立した文字として扱う必要があります。end
'e'
'e'
'e'
しかし、私がするとき
double d;
char c;
sscanf("3ex", "%lf%c", &d, &c);
フォーマット指定子のとのsscanf
両方を消費していることに気付きました。変数は値を受け取ります。変数はその中で終わります。これは、2 つの理由から私には奇妙に見えます。'3'
'e'
%lf
d
3.0
c
'x'
まず、言語仕様は書式指定子strtod
の振る舞いを記述するときに参照するので、%f
直感的%lf
に入力を同じように扱うstrtod
(つまり、終点と同じ位置を選ぶ) ことを期待しました。scanf
ただし、歴史的には、入力ストリームに返される文字は 1 つだけであると想定されていたことを知っています。scanf
これにより、1 文字で実行できる先読みの距離が制限されます。上記の例では、少なくとも 2 文字の先読みが必要です。したがって、入力ストリームからと の両方を%lf
消費したという事実を受け入れるとしましょう。'3'
'e'
しかし、次に 2 番目の問題に直面します。それを typesscanf
に変換する必要があります。浮動小数点定数の有効な表現ではありません (6.4.4.2 によれば、指数値はオプションではありません)。私はこの入力を間違ったものとして扱うことを期待しています:変換中に終了し、戻ってそのままにし、 変更しません。ただし、上記は正常に完了します ( を返します)。"3e"
double
"3e"
sscanf
%lf
0
d
c
sscanf
2
この動作は、標準ライブラリの GCC 実装と MSVC 実装の間で一貫しています。
したがって、私の質問は、C 言語標準ドキュメントのどこでsscanf
、上記の 2 つの点を参照して、上記のように動作することが許可さstrtod
れている"3e"
かということです。
私の実験結果を見ると、おそらくsscanf
の動作を「リバース エンジニアリング」することができstrtod
ます。そのようにして、'e'
によって消費され%lf
、無視されstrtod
ます。しかし、言語仕様にはそれだけでしたか?