سؤال

ما هو التحديد التنسيق الصحيح ل double في printf؟ فعلا %f أو هو %lf؟ أعتقد أنه %f, ، لكنني لست متأكدًا.

عينة الكود

#include <stdio.h>

int main()
{
   double d = 1.4;
   printf("%lf", d); // Is this wrong?
}
هل كانت مفيدة؟

المحلول

"%f" هو التنسيق الصحيح (أو واحد على الأقل) لمضاعفة. هناك هو لا يوجد تنسيق ل float, ، لأنه إذا حاولت تمرير أ float إلى printf, ، سيتم ترقيته إلى double قبل printf يستقبلها1. "%lf" مقبول أيضًا بموجب المعيار الحالي - l تم تحديده على أنه ليس له أي تأثير إذا تليها f محدد التحويل (من بين أمور أخرى).

لاحظ أن هذا مكان واحد printf سلاسل التنسيق تختلف اختلافا كبيرا scanffscanf, ، وما إلى ذلك) تنسيق السلاسل. للإخراج ، أنت تمر القيمة, ، والتي سيتم ترقيتها من float إلى double عند تمريرها كمعلمة متنوعة. للدخول أنت تمر أ مؤشر, ، الذي لم يتم الترويج له ، لذلك عليك أن تخبر scanf سواء كنت تريد قراءة أ float أو أ double, ، وذلك ل scanf, %f يعني أنك تريد قراءة أ float و %lf يعني أنك تريد قراءة أ double (ولما يستحق الأمر ، long double, ، انت تستخدم %Lf احد الامرين printf أو scanf).


1. C99 ، الفقرة 6.5.2.2/6: "إذا كان التعبير الذي يشير إلى الوظيفة المدعوة له نوع لا يتضمن نموذجًا أوليًا ، يتم تنفيذ العروض الترويجية الصحيحة على كل وسيطة ، ويتم تعزيز الوسيطات التي تحتوي على تعويم النوع إلى مضاعفة. وتسمى هذه الترقيات الوسيطة الافتراضية. " في C ++ ، تختلف الصياغة إلى حد ما (على سبيل المثال ، لا تستخدم كلمة "النموذج الأولي") ولكن التأثير هو نفسه: جميع المعلمات المتنوعة تخضع للترقيات الافتراضية قبل استلامها بواسطة الوظيفة.

نصائح أخرى

Given the C99 standard (namely, the N1256 draft), the rules depend on the function kind: fprintf (printf, sprintf, ...) or scanf.

Here are relevant parts extracted:

Foreword

This second edition cancels and replaces the first edition, ISO/IEC 9899:1990, as amended and corrected by ISO/IEC 9899/COR1:1994, ISO/IEC 9899/AMD1:1995, and ISO/IEC 9899/COR2:1996. Major changes from the previous edition include:

  • %lf conversion specifier allowed in printf

7.19.6.1 The fprintf function

7 The length modifiers and their meanings are:

l (ell) Specifies that (...) has no effect on a following a, A, e, E, f, F, g, or G conversion specifier.

L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to a long double argument.

The same rules specified for fprintf apply for printf, sprintf and similar functions.

7.19.6.2 The fscanf function

11 The length modifiers and their meanings are:

l (ell) Specifies that (...) that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to double;

L Specifies that a following a, A, e, E, f, F, g, or G conversion specifier applies to an argument with type pointer to long double.

12 The conversion specifiers and their meanings are: a,e,f,g Matches an optionally signed floating-point number, (...)

14 The conversion specifiers A, E, F, G, and X are also valid and behave the same as, respectively, a, e, f, g, and x.

The long story short, for fprintf the following specifiers and corresponding types are specified:

  • %f -> double
  • %Lf -> long double.

and for fscanf it is:

  • %f -> float
  • %lf -> double
  • %Lf -> long double.

يمكن أن يكون %f, %g أو %e اعتمادًا على كيفية تنسيق الرقم. نرى هنا لمزيد من التفاصيل. ال l مطلوب المعدل في scanf مع double, ، ولكن ليس في printf.

الصحيح printf تنسيق ل double هو %lf, ، بالضبط كما استخدمته. لا حرج في الكود الخاص بك.

شكل %lf في printf لم يكن مدعومًا في الإصدارات القديمة (قبل C99) من لغة C ، والتي أنشأت "عدم الاتساق" السطحية بين مواصفات التنسيق لصالح double في printf و scanf. تم إصلاح هذا التناقض السطحي في C99.

لذلك في C Modern ، من المنطقي التفضيل لاستخدامه %f مع float, %lf مع double و %Lf مع long double باستمرار في كليهما printf و scanf.

%Lf (لاحظ العاصمة L) هل تنسيق محدد إلى عن على زوجي طويل.

من أجل سهل doubles, ، أيضاً %e, %E, %f, %g أو %G سوف تفعل.

لمضاعفة يمكنك ببساطة استخدام %lf أو يمكنك استخدام أي من المتابعة حسب تفضيلاتك

%e أو %E للقيم في التنسيق الأسي

%g أو %G للحصول على تدوين طبيعي أو أسي ، أيهما أكثر ملاءمة لحجمها.

اقرأ المزيد في هنا قائمة بجميع محددات التنسيق في ج

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top