回答:
"%f"doubleの(または少なくとも1つの)正しい形式です。ありませんのためのフォーマットはfloatあなたが合格しようとした場合ので、floatにprintf、それはに昇格することがありますdouble前にprintf、それを受信1。"%lf"現在の標準でも許容lされます-は、f変換指定子が続く場合(特に)、効果がないと指定されています。
これは、printfフォーマット文字列がフォーマット文字列scanf(およびfscanfなど)と大幅に異なる1つの場所であることに注意してください。出力の場合、値を渡します。可変パラメーターとして渡されると、からfloatに昇格しdoubleます。入力の場合は、昇格されていないポインターを渡すのでscanf、a floatまたはa のどちらを読みたいかを伝える必要がありますdouble。したがって、forはscanf、%faを読みたいことfloatを%lf意味し、a double(および、価値は、のためにlong double、使用%Lfのいずれかのためprintfかscanf)。
1. C99、§6.5.2.2/ 6:「呼び出された関数を表す式にプロトタイプを含まない型がある場合、整数の昇格が各引数で実行され、型がfloatの引数が倍に昇格されます。これらはデフォルトの引数プロモーションと呼ばれます。」C ++では表現が多少異なります(たとえば、「プロトタイプ」という単語は使用されません)が、効果は同じです。すべての可変パラメータは、関数が受け取る前にデフォルトのプロモーションを受けます。
g++不良品%lfでコンパイル-Wall -Werror -pedantic:error: ISO C++ does not support the ‘%lf’ gnu_printf format
lは拡張機能でした。C99 / 11およびC ++ 11標準では、それを可能にする実装が必要です。
scanf ない希望doubleSで表される%lf:それはそれは期待と文句を言いfloat *、見つかったdouble *だけで%f。
scanfので、それが読み何を保存する場所へのポインタを取る必要があり、一方、スペースが尖っ-にされているどのように大きな知っているprintf「デフォルト引数のプロモーションが」として両端を平均値そのものをとり、そしてdoubleので、S lであります基本的にオプションです。
与えられたC99の標準(すなわち、N1256用のfprintf(のprintf、sprintfの、...)やscanf関数:ドラフト)、ルールは、関数の種類によって異なります。
抽出された関連パーツは次のとおりです。
序文
この第2版は、ISO / IEC 9899 / COR1:1994、ISO / IEC 9899 / AMD1:1995、およびISO / IEC 9899 / COR2:1996によって修正および修正された、第1版のISO / IEC 9899:1990を取り消して置き換えます。前版からの主な変更点は次のとおりです。
%lfで使用できる変換指定子printf7.19.6.1
fprintf関数7長さ修飾子とその意味は次のとおりです。
l(エル)(...)が後続のa、A、e、E、f、F、g、またはG変換指定子に影響しないことを指定します。
L次のa、A、e、E、f、F、g、またはG変換指定子がlong double引数に適用されることを指定します。
に指定されたものと同じルールfprintfがprintf、sprintfおよび同様の関数に適用されます。
7.19.6.2
fscanf関数11長さ修飾子とその意味は次のとおりです。
l(エル)次のa、A、e、E、f、F、g、またはG変換指定子が、タイプポインターがdoubleの引数に適用されることを指定します(...)。
L次のa、A、e、E、f、F、g、またはG変換指定子がlong doubleへの型ポインターを持つ引数に適用されることを指定します。
12変換指定子とその意味は次のとおりです。a、e、f、gオプションで符号付きの浮動小数点数と一致します(...)
14変換指定子A、E、F、G、およびXも有効であり、それぞれ、a、e、f、g、およびxと同じように動作します。
fprintf次の指定子と対応するタイプが指定されているため、簡単に言えば、
%f ->ダブル%Lf ->ロングダブル。そしてfscanfそれは:
%f ->フロート%lf ->ダブル%Lf ->ロングダブル。それは%f、%gまたは%e数値をどのようにフォーマットするかによって異なります。詳細はこちらをご覧ください。l修飾子はで必要とされるscanfとdouble、しかし、NOT IN printf。
l小文字)修飾子は整数型(cplusplus.com/reference/clibrary/cstdio/printf)用でありL、浮動小数点型用です。さらに、L修飾子はlong doubleプレーンではなくを期待しdoubleます。
l必要ではないことを私は言ったことはありません。printfdouble
形式%lfは、使用したとおりのの完全に正しいprintf形式ですdouble。コードに問題はありません。
形式%lfin printfは、C言語の古い(C99より前の)バージョンではサポートされていなかったためdouble、in printfとの形式指定子間に表面的な「矛盾」が生じていましたscanf。その表面的な矛盾はC99で修正されました。
あなたが使用する必要はありません%lfとdoubleの中でprintf。%f必要に応じて使用することもできます(%lfおよびと%f同等ですprintf)。しかし、現代のCにそれが使用することを好むために完璧な理にかなっている%fとfloat、%lfとdoubleと%Lfとlong double一貫の両方で、printfとscanf。
scanf()、"%f"、"%lf"一致しfloat *, double *ていない、float, doubleとして最後の行で暗示。
%Lf(大文字に注意L)はlong doubleの形式指定子です。
平野のためにdoublesどちらかの、%e、%E、%f、%gまたは%G行います。
%gとは%G?
"%lf"は未定義です。C99およびC11ライブラリでは、と同じであると定義されています"%f"。