printfのdoubleの正しいフォーマット指定子

2010年11月24日に質問されました。  ·  閲覧回数 1.1M回  ·  ソース

Leopard picture
2010年11月24日

printfのdoubleの正しいフォーマット指定子は何ですか? それは%f %lfですか、それとも%fだと思いますが、よくわかりません。

コードサンプル

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}

回答

Jerry Coffin picture
2010年11月24日
653

"%f"は、doubleの(または少なくとも1つの)正しい形式です。 floatprintfに渡そうとすると、 printf前にdoubleにプロモートされるため、 floatの形式はありません。 printfはそれを受け取ります1"%lf"は、現在の標準でも受け入れられます。 l後に、(とりわけ) f変換指定子が続く場合、効果がないものとして指定されます。

これは、 printf形式の文字列がscanf (およびfscanfなど)形式の文字列と大幅に異なる1つの場所であることに注意してください。 出力には、を渡します。floatからdoubleに昇格されます。 入力の場合、プロモートされていないポインタを渡すので、 floatdoubleどちらを読み取るかをscanfに指示する必要があります。したがって、 scanf%fは、 floatを読みたいことを意味し、 %lfは、 doubleを読みたいことを意味します(そして、その価値については、 long double場合、 printfまたはscanfいずれかにprintf %Lfを使用します)。


1. C99、§6.5.2.2/ 6:「呼び出された関数を示す式にプロトタイプを含まない型がある場合、整数の昇格が各引数で実行され、float型の引数がdoubleに昇格されます。これらはデフォルトの引数プロモーションと呼ばれます。」

mloskot picture
2012年04月29日
63

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変換指定子はprintf許可されています

7.19.6.1 fprintf関数

7長さ修飾子とその意味は次のとおりです。

l (ell)(...)が後続のa、A、e、E、f、F、g、またはG変換指定子に影響を与えないことを指定します。

L次のa、A、e、E、f、F、g、またはG変換指定子がlongdouble引数に適用されることを指定します。

fprintf指定されたのと同じルールが、 printfsprintfおよび同様の関数に適用されます。

7.19.6.2 fscanf関数

11長さ修飾子とその意味は次のとおりです。

l (ell)次のa、A、e、E、f、F、g、またはG変換指定子がdoubleへの型ポインターを持つ引数に適用されることを指定します(...)。

L次のa、A、e、E、f、F、g、またはG変換指定子が、longdoubleへの型ポインターを持つ引数に適用されることを指定します。

12変換指定子とその意味は次のとおりです。a、e、f、gオプションで符号付きの浮動小数点数に一致します(...)

14変換指定子A、E、F、G、およびXも有効であり、それぞれa、e、f、g、およびxと同じように動作します。

簡単に言うと、 fprintf 、次の指定子と対応するタイプが指定されます。

  • %f ->ダブル
  • %Lf ->ロングダブル。

fscanf場合は次のとおりです。

  • %f ->フロート
  • %lf ->ダブル
  • %Lf ->ロングダブル。
vitaut picture
2010年11月24日
25

数値のフォーマット方法に応じて、 %f%gまたは%eかになります。 詳細については、こちらをご覧ください。 l修飾子はscanfdoubleで必要ですが、 printfでは必要ありません。

AnT picture
2016年05月08日
16

フォーマット%lfは、使用したとおりのdouble完全に正しいprintfフォーマットです。 コードに問題はありません。

フォーマット%lfprintfために書式指定子の間に表面的な"矛盾"を作成したC言語の古い(事前C99)のバージョンでサポートされていませんでしたdoubleprintfおよびscanf 。 その表面的な不整合はC99で修正されました。

printf doubleprintf %lfを使用する必要はありません。 必要に応じて、 %fも使用できます( %lf%fprintf同等です)。 しかし、最近のCでは、 %ffloat%lfdouble%Lflong double使用することを選択するのは完全に理にかなっています。 printfscanf両方で一貫して。

Fr&#233;d&#233;ric Hamidi picture
2010年11月24日
10

%Lf (ノートに資本L )された書式指定子のために長いダブルス

プレーンなdoubles場合、 %e%E%f%gまたは%Gいずれかで