printf

رسم توضيحي لبنية دالة printf. الوسيط الأول للدالة هو سلسلة نصية نموذجية، قد تحتوي على مُحدِّدات تنسيق، تُعرَض بعلامة النسبة المئوية (%). تُعلِّم مُحدِّدات التنسيق دالة printf كيفية تفسير وإخراج القيم المُعطاة في الوسائط المُقابلة التي تلي سلسلة التنسيق. تستبدل دالة printf مُحدِّدات التنسيق بمحتويات الوسائط المتبقية بعد تفسيرها، ثم تُخرِج النتيجة.
مثال على استدعاء دالة printf

دالة printf هي دالة من مكتبة C القياسية، وهي أيضًاأمر طرفي (shell) في نظام لينكس، تُستخدم لتنسيق النصوص وكتابتها إلى المخرج القياسي . تقبل الدالة وسيطًا من نوع سلسلة نصية (C-string) يُمثل التنسيق ، وعددًا متغيرًا من وسائط القيم التي تُحوّلها الدالةإلى سلسلة نصية وفقًا للتنسيق. يؤدي عدم تطابق مُحددات التنسيق مع عدد ونوع القيم إلى سلوك غير مُحدد ، وقد يتسبب ذلك في تعطل البرنامجأوظهور ثغرات أمنية .

تُشفّر سلسلة التنسيق كلغة قالب تتألف من نص حرفي ومحددات تنسيق، يحدد كل منها كيفية تسلسل القيمة. عند معالجة سلسلة التنسيق من اليسار إلى اليمين، تُستخدم قيمة لاحقة لكل محدد تنسيق موجود. يبدأ محدد التنسيق بحرف، %ويتبعه حرف واحد أو أكثر يحدد كيفية تسلسل القيمة.

توفر المكتبة القياسية وظائف أخرى مشابهة تُشكل عائلة من الوظائف الشبيهة بـ printf . تشترك هذه الوظائف في نفس إمكانيات التنسيق، ولكنها توفر سلوكيات مختلفة، مثل الإخراج إلى وجهة مختلفة أو إجراءات أمان تحد من التعرض للثغرات الأمنية. وقد تم تطبيق وظائف عائلة printf في سياقات برمجة حاسوبية أخرى (أي لغات برمجة ) بنفس الصيغة والدلالات أو بصيغة مشابهة .

تُكمل دالة scanf () في مكتبة C القياسية دالة printf من خلال توفير مدخلات منسقة (المعروفة أيضًا باسم التحليل المعجمي ، أو التحليل النحوي ) عبر صيغة سلسلة تنسيق مماثلة.

اسم الدالة printf هو اختصار لعبارة print formatted ، حيث تشير print إلى الإخراج إلى الطابعة، مع أن وظيفتها لا تقتصر على ذلك. اليوم، تشير print إلى الإخراج إلى أي بيئة نصية مثل سطر الأوامر أو ملف .

تاريخ

خمسينيات القرن العشرين: فورتران

استخدمت لغات البرمجة المبكرة مثل فورتران عبارات خاصة ذات بنية مختلفة عن العمليات الحسابية الأخرى لإنشاء أوصاف التنسيق. [ 1 ] في هذا المثال، يتم تحديد التنسيق على السطر601ويشير الأمر PRINT[ a ] إليه برقم السطر:

PRINT 601 , IA , IB , AREA 601 FORMAT ( 4 H A = , I5 , 5 H B = , I5 , 8 H AREA = , F10 . 2 , 13 H SQUARE UNITS )

بموجب هذا:

قد يبدو الناتج مع وسائط الإدخال 100، 200و ، 1500.25كما يلي:

أ = ١٠٠ ب = ٢٠٠ المساحة = ١٥٠٠.٢٥ وحدة مربعة

ستينيات القرن العشرين: BCPL و ALGOL 68

ظهرت لغة BCPL عام 1967. [ 2 ] تضمنت مكتبتها writefروتينًا يشبه أي استدعاء دالة آخر. [ 3 ] يبدو تطبيقها كمثال على ذلك:

WRITEF("%I2-QUEENS PROPLEM HAS %I5 SOLUTIONS*N", NUMQUEENS, COUNT) 

بموجب هذا:

  • %I2يشير إلى عدد صحيح بعرض 2 (يتم عكس ترتيب عرض ونوع حقل مواصفات التنسيق مقارنةً بـ C printf
  • %I5يشير إلى عدد صحيح بعرض 5؛
  • *Nهو تسلسل هروب في لغة BCPL يمثل حرف سطر جديد (الذي تستخدم لغة C تسلسل الهروب الخاص به ).\n

كان لدى لغة ALGOL 68 أيضًا واجهة برمجة تطبيقات للدوال، ولكنها استخدمت صيغة خاصة للتنسيق:

printf (( $ "Color " g ", number1 " 6d " , " ", number2 " 4zd " , "", hex " 16r2d " , "", float " -d.2d " , " ", unsigned value " -3d ." l$ " , "red" , 123456 , 89 , BIN 255 , 3.14 , 250 ));

يُبسّط استخدام صيغة الدوال العادية للطباعة اللغة، ويسمح بتنفيذ الطباعة ضمن اللغة نفسها. في معظم اللغات الحديثة في تلك الحقبة، لا تُعدّ عمليات الإدخال والإخراج جزءًا من الصيغة. ومع ذلك، لم يكن يتم عادةً التحقق من التنسيق للتأكد من مطابقته لنوع (أو حتى عدد) القيم المراد طباعتها. [ 4 ]

سبعينيات القرن العشرين: ج

في عام 1973، printfتم تضمينها كروتين مكتبة C القياسية كجزء من الإصدار 4 من يونكس . [ 5 ]

التسعينيات: أوامر شل

في عام 1990، أُدرج أمر printfshell ، المصمم على غرار دالة مكتبة C القياسية، مع نظام التشغيل 4.3BSD-Reno . [ 6 ] وفي عام 1991، أُدرج أمر آخر مع GNU shellutils (التي أصبحت الآن جزءًا من GNU Core Utilities )، ويختلف بناء جملة (الخيارات، الوسائط، إلخ) أمر shell هذا عن دالة لغة C، على سبيل المثال: لا يستخدم "قسم التنسيق" الوسائط الموضعية [ 7 ] مع رمز "$" (n$) بنفس طريقة الدالة.printfprintf()

str = "AA BB CC" # سلسلة نصية بسيطة بثلاثة حقولتعيين -- $str # تحويل الحقول إلى معلمات موضعيةprintf "%s " $2 $3 $1 ; echo # في لغة C، تستخدم دالة printf() الرمز 2$ 3$..# مطبوعات: BB CC AA

العقد الأول من القرن الحادي والعشرين: جافا

في عام 2004، صدرت جافا 5.0 (1.5)، والتي وسّعت الفئة java.io.PrintStream، مضيفةً دالةً تُسمى printf()تعمل بشكلٍ مشابهٍ لدالةٍ printf()في لغة C. وبالتالي، لطباعة سلسلة نصية مُنسّقة إلى دفق الإخراج القياسي، يتم استخدام هذه الدالة System.out.printf(). وقد أضافت جافا لاحقًا هذه الدالة formatإلى فئة السلاسل النصية الخاصة بها java.lang.String. [ 8 ]

العقد الأول من القرن الحادي والعشرين: - سلامة تنسيق W

إن الحاجة إلى القيام بشيء ما حيال مجموعة المشاكل الناتجة عن نقص سلامة النوع قد دفعت إلى محاولة جعل المترجمات printfعلى دراية بذلك.

يُتيح خيار -Wformatمجموعة مُترجمات GNU (GCC) إجراء فحوصات أثناء الترجمةprintf للاستدعاءات، مما يمكّن المُترجم من اكتشاف مجموعة فرعية من الاستدعاءات غير الصالحة (وإصدار تحذير أو خطأ، وإنهاء عملية الترجمة، وفقًا لما تحدده علامات أخرى). [ 9 ]

لأن المترجم يفحص printfمحددات التنسيق، فإن هذه الميزة توسع بشكل فعال التحليل الثابت في لغة C ليشمل جوانب التنسيق.

عقد 2020: std::print

أضافت لغة C++ دعمًا للإدخال والإخراج باستخدام عامل التشغيل << لتجنب مشاكل الأمان في دالة printf. [ 10 ] يعتمد هذا على نوع الوسائط لتحديد الكود المراد تنفيذه لطباعتها، متجنبًا بذلك الأعطال المحتملة مع سلاسل التنسيق. مع ذلك، قد يكون بناء الجملة مطولًا (خاصةً عند ضبط خيارات مثل الدقة)، ولذا تبقى دالة printf متاحة في C++ وغالبًا ما تُستخدم بدلًا منها.

أضافت لغة C++20 واجهة برمجة تطبيقات جديدة تستخدم سلسلة نصية تتكون من نص حرفي وعناصر نائبة متبوعة بالقيم المراد طباعتها. [ 11 ] تستخدم سلسلة التنسيق أقواسًا معقوفة بدلًا من علامات النسبة المئوية، استنادًا إلى الصيغة المستخدمة في مكتبة بايثون القياسية : [ 11 ] [ 12 ]

std::format("The hex value of {} is {:x}.",name,value)

يُوصى باستخدام مكتبة fmtlib الخاصة بفيكتور زفيروفيتش [ 11 ] [ 13 ] ، والتي تُحوّل أنواع السلاسل والوسائط إلى كائن تنسيق مُحسَّن أثناء الترجمة، مما يضمن سلامة النوع واكتشاف أخطاء بناء الجملة أثناء الترجمة. قدّمت لغة C++23 الدالتين و اللتين جمعتا بين التنسيق والإخراج، وبالتالي تُعدّان بديلاً وظيفياً لـ . [ 14 ] من الممكن إنشاء مُترجم من سلسلة printf % إلى كائن التنسيق نفسه [ 15 وهذا من شأنه أن يُنتج دالة printf آمنة النوع ، ولكن لم يُضَف هذا إلى المواصفات. لم يُقدَّم أي تحديث مُماثل لدالة scanf ، على الرغم من اقتراح تحديث مُستند إلى مكتبة scnlib . [ 16 ]std::print()std::println()printf() 

تستطيع هذه الدوال (بالإضافة إلى ذلك std::to_chars) طباعة الأعداد العشرية بدقة باستخدام أقل عدد ممكن من الأرقام اللاحقة، وهي ميزة كانت تفتقر إليها دالة printf لفترة طويلة . ومن الميزات المفيدة الأخرى أنها تتجاهل الإعدادات المحلية .

مُحدد التنسيق

يتم تحديد تنسيق القيمة باستخدام علامات التنسيق في سلسلة التنسيق. على سبيل المثال، يُخرج ما يلي Your age isقيمة المتغير age بالتنسيق العشري.

printf ( "عمرك هو %d" , age );

بناء الجملة

صيغة مُحدِّد التنسيق هي:

%[ parameter ][ flags ][ width ][. precision ][ length ] type

حقل المعلمات

حقل المعلمة اختياري. في حال تضمينه، فإن مطابقة المحددات بالقيم لا تتم بشكل تسلسلي. القيمة العدديةنيحدد هذا الخيار قيمة المعامل رقم n. هذا امتداد لمعيار POSIX ، وليس معيار C99 .

نصوصف
ن $يمثل n فهرس معلمة القيمة المراد تسلسلها باستخدام محدد التنسيق هذا

يُتيح هذا الحقل استخدام القيمة نفسها عدة مرات في سلسلة التنسيق بدلاً من تمرير القيمة عدة مرات. إذا تضمن مُحدِّد ما هذا الحقل، فيجب أن تتضمنه المُحدِّدات اللاحقة أيضاً.

على سبيل المثال،

printf ( "%2$d %2$#x; %1$d %1$#x" , 16 , 17 );

المخرجات:17 0x11؛ 16 0x10

يُعد هذا الحقل مفيدًا جدًا لترجمة الرسائل إلى لغات طبيعية مختلفة تستخدم ترتيبات كلمات مختلفة .

في واجهة برمجة تطبيقات ويندوز ، يتم دعم هذه الميزة عبر وظيفة مختلفة printf_p.

حقل الأعلام

يمكن أن يحتوي حقل العلامات على صفر أو أكثر من (بأي ترتيب):

نصوصف
-قم بمحاذاة مخرجات هذا العنصر النائب إلى اليسار؛ الوضع الافتراضي هو محاذاة المخرجات إلى اليمين.
+يُضيف علامة زائد للقيمة الموجبة؛ افتراضيًا، لا تحتوي القيمة الموجبة على بادئة.
(فضاء)يُضيف مسافةً في بداية القيمة الموجبة؛ ويتم تجاهل هذه الخطوة إذا كانت علامة الجمع (+ ) موجودة؛ افتراضيًا، لا تحتوي القيمة الموجبة على بادئة.
0عند تحديد خيار "العرض"، يتم إضافة أصفار بدلاً من المسافات للأنواع الرقمية؛ على سبيل المثال، ينتجprintf("%4X",3)"3"، بينما ينتجprintf("%04X",3);"0003"
'يتم تطبيق فاصلة تجميع الآلاف على العدد الصحيح أو الأس في العدد العشري
8صيغة بديلة: بالنسبة للأنواع g و G ، لا تُحذف الأصفار اللاحقة. بالنسبة للأنواع f و F و e و E و g و G ، يحتوي الناتج دائمًا على فاصلة عشرية. بالنسبة للأنواع o و x و X ، يُضاف النص 0 و 0x و 0X ، على التوالي، قبل الأرقام غير الصفرية.

حقل العرض

يُحدد حقل العرض الحد الأدنى لعدد الأحرف المطلوب إخراجها. إذا أمكن تمثيل القيمة بعدد أحرف أقل، فسيتم إضافة مسافات إلى يسارها بحيث يكون الناتج هو عدد الأحرف المحدد. أما إذا تطلبت القيمة عددًا أكبر من الأحرف، فسيكون الناتج أطول من العرض المحدد. ولا يتم اقتطاع أي قيمة.

على سبيل المثال، يحدد عرضًا قدره 3 ويُخرجprintf("%3d",12);12مع ترك مسافة على اليسار لإخراج 3 أحرف. يُخرج الاستدعاءprintf("%3d",1234);1234وهو عبارة عن 4 أحرف لأن هذا هو الحد الأدنى للعرض لتلك القيمة على الرغم من أن العرض المحدد هو 3.

إذا تم حذف حقل العرض، فسيكون الناتج هو الحد الأدنى لعدد الأحرف للقيمة.

إذا تم تحديد الحقل على أنه *، فسيتم قراءة قيمة العرض من قائمة القيم في الاستدعاء. [ 17 ] على سبيل المثال، المخرجاتprintf("%*d",3,10);10(<space>10) حيث المعامل الثاني، 3، هو العرض (يتطابق مع *) و 10هو القيمة المراد تسلسلها (يتطابق مع d).

على الرغم من أنها ليست جزءًا من حقل العرض، إلا أن الصفر البادئ يُفسر على أنه علامة الحشو الصفري المذكورة أعلاه، ويتم التعامل مع القيمة السالبة على أنها القيمة الموجبة بالاقتران مع -علامة المحاذاة إلى اليسار المذكورة أعلاه أيضًا.

يمكن استخدام حقل العرض لتنسيق القيم كجدول (إخراج جدولي). ولكن، لا تتم محاذاة الأعمدة إذا كانت أي قيمة أكبر من العرض المحدد. على سبيل المثال، لاحظ أن قيمة السطر الأخير (1234) لا يتناسب مع العمود الأول بعرض 3 وبالتالي فإن العمود غير محاذٍ.

 1 1 12 12 123 123 1234 123

مجال الدقة

يُحدد حقل الدقة عادةً الحد الأقصى للناتج، وفقًا لنوع التنسيق. بالنسبة للأنواع العددية ذات الفاصلة العائمة ، يُحدد عدد الأرقام على يمين الفاصلة العشرية التي يجب تقريب الناتج إليها؛ وبالنسبة %gللأنواع الأخرى ، %Gيُحدد العدد الإجمالي للأرقام المعنوية (قبل وبعد الفاصلة العشرية، باستثناء الأصفار البادئة واللاحقة) التي يجب التقريب إليها. أما بالنسبة لنوع السلسلة النصية ، فيُحدد عدد الأحرف التي يجب إخراجها، وبعدها يتم اقتطاع السلسلة.

يمكن حذف حقل الدقة، أو استخدام قيمة عددية صحيحة، أو قيمة ديناميكية عند تمريرها كوسيط إضافي عند الإشارة إليها بعلامة النجمة ( **). على سبيل المثال، المخرجاتprintf("%.*s",3,"abcdef");أبجد.

حقول الطول

يمكن حذف حقل الطول أو أن يكون أيًا مما يلي:

نصوصف
hhبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح بحجم int والذي تمت ترقيته من نوع char .
حبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح بحجم int والذي تمت ترقيته من نوع short .
لبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح طويل الحجم.

بالنسبة لأنواع البيانات ذات الفاصلة العائمة، يتم تجاهل ذلك. يتم دائمًا ترقية وسائط الفاصلة العائمة إلى نوع double عند استخدامها في استدعاء varargs . [ 18 ]

llبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح طويل جدًا (long long ).
لبالنسبة لأنواع الأعداد العشرية، يتسبب ذلك في توقع دالة printf لوسيط من نوع long double .
zبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح بحجم size_t .
جبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح بحجم intmax_t .
تبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح بحجم ptrdiff_t .

ظهرت خيارات الطول الخاصة بالمنصة قبل الاستخدام الواسع النطاق لامتدادات ISO C99، بما في ذلك:

نصوصفالمنصات الشائعة
أنابالنسبة لأنواع الأعداد الصحيحة الموقعة، يجعل هذا الأمر دالة printf تتوقع وسيطًا من نوع عدد صحيح بحجم ptrdiff_t ؛ أما بالنسبة لأنواع الأعداد الصحيحة غير الموقعة، فيجعل دالة printf تتوقع وسيطًا من نوع عدد صحيح بحجم size_tWin32 / Win64
I32بالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا من نوع عدد صحيح 32 بت ( كلمة مزدوجة ).Win32/Win64
الطريق السريع I64بالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا صحيحًا من 64 بت (كلمة رباعية)Win32/Win64
qبالنسبة لأنواع الأعداد الصحيحة، يتسبب ذلك في أن تتوقع دالة printf وسيطًا صحيحًا من 64 بت (كلمة رباعية)بي إس دي

يتضمن معيار ISO C99 inttypes.hملف رأس يحتوي على عدد من وحدات الماكرو للبرمجة عبر المنصات المختلفةprintf . على سبيل المثال: يحدد تنسيقًا عشريًا لعدد صحيح مُوقّع 64 بت . بما أن وحدات الماكرو تُقيّم إلى سلسلة نصية حرفية ، ويقوم المُصرّف بدمج السلاسل النصية المتجاورة، فإن التعبير يُترجم إلى سلسلة نصية واحدة.printf("%"PRId64,t);"%"PRId64

تتضمن وحدات الماكرو ما يلي:

الماكرووصف
PRId32عادةً ما يعادل I32d ( Win32/Win64 ) أو d
PRId64عادةً ما يكون مكافئًا لـ I64d ( Win32/Win64 ) أو lld ( منصات 32 بت ) أو ld ( منصات 64 بت ).
PRIi32عادةً ما يعادل I32i ( Win32/Win64 ) أو i
PRIi64عادةً ما يكون مكافئًا لـ I64i ( Win32/Win64 ) أو lli ( منصات 32 بت ) أو li ( منصات 64 بت ).
PRIu32عادةً ما يعادل I32u ( Win32/Win64 ) أو u
PRIu64عادةً ما يكون مكافئًا لـ I64u ( Win32/Win64 ) أو llu ( منصات 32 بت ) أو lu ( منصات 64 بت ).
PRIx32عادةً ما يعادل I32x ( Win32/Win64 ) أو x
PRIx64عادةً ما يكون مكافئًا لـ I64x ( Win32/Win64 ) أو llx ( منصات 32 بت ) أو lx ( منصات 64 بت ).

حقل النوع

يمكن أن يكون حقل النوع أيًا مما يلي:

نصوصف
%يُخرج رمز النسبة المئوية (%) حرفيًا ؛ ولا يقبل علامات أو حقول العرض أو الدقة أو الطول.
د ، يعدد صحيح (موقع) مُنسق كعدد عشري؛ %d و %i مترادفان إلا عند استخدامهما معscanf
uعدد صحيح غير مُوقّع مُنسّق كعدد عشري.
f , Fيتم تنسيق الأرقام المزدوجة كنقاط ثابتة ؛ يختلف f و F فقط في كيفية طباعة السلاسل الخاصة بالعدد اللانهائي أو NaN ( inf و infinity و nan لـ f ؛ INF و INFINITY و NAN لـ F ).
هـ ، هـيُكتب العدد d بالصيغة المزدوجة كما في الصيغة الأسية d . ddddd ; ينتج عن E قيمة E بدلاً من e لإدخال الأس؛ يحتوي الأس دائمًا على رقمين على الأقل؛ إذا كانت القيمة صفرًا، يكون الأس 00 ؛ في نظام ويندوز، يحتوي الأس على ثلاثة أرقام افتراضيًا، على سبيل المثال 1.5e002 ، ولكن يمكن تغيير ذلك باستخدام دالة خاصة بنظام مايكروسوفت_set_output_format
g , Gيُنسق العدد العشري المزدوج إما بنظام الفاصلة الثابتة أو بنظام الأس، أيهما أنسب لقيمته؛ يستخدم g أحرفًا صغيرة، بينما يستخدم G أحرفًا كبيرة؛ يختلف هذا النوع قليلاً عن نظام الفاصلة الثابتة في عدم تضمين الأصفار غير المهمة على يمين الفاصلة العشرية، وفي أن حقل الدقة يُحدد العدد الإجمالي للأرقام المعنوية بدلاً من الأرقام التي تلي الفاصلة العشرية؛ لا تُدرج الفاصلة العشرية في الأعداد الصحيحة.
س ، سعدد صحيح غير مُوقّع مُنسّق بنظام العد الست عشري ؛ يستخدم x أحرفًا صغيرة، بينما يستخدم X أحرفًا كبيرة.
oعدد صحيح غير مُوقّع مُنسّق كثماني
sسلسلة منتهية بـ null
جشخصية
صمؤشر مُنسق بطريقة محددة من قبل التنفيذ
أ ، أيُستخدم الرقم المزدوج في التدوين الست عشري، ويبدأ بـ 0x أو 0X . يستخدم الحرف a أحرفًا صغيرة، بينما يستخدم الحرف A أحرفًا كبيرة [ 19 ]
نلا يُخرج أي شيء سوى كتابة عدد الأحرف المكتوبة حتى الآن في مُعامل مؤشر عدد صحيح ؛ في جافا، هذا يطبع سطرًا جديدًا [ 20 ]

تنسيق نوع البيانات المخصص

تتمثل إحدى الطرق الشائعة للتعامل مع التنسيق باستخدام نوع بيانات مخصص في تنسيق قيمة نوع البيانات المخصص في سلسلة نصية ، ثم استخدام المحدد لتضمين القيمة المتسلسلة في رسالة أكبر.%s

تتيح بعض الدوال الشبيهة بـ printf إمكانية توسيع اللغة المصغرة القائمة على أحرف الهروب ، مما يسمح للمبرمج باستخدام دالة تنسيق محددة للأنواع غير المدمجة. إحدى هذه الدوال هي دالة glibc ( التي أصبحت مهملة الآن ) . ومع ذلك، نادرًا ما تُستخدم نظرًا لتعارضها مع التحقق الثابت من سلاسل التنسيق . وهناك أيضًا دوال Vstr المخصصة للتنسيق ، والتي تسمح بإضافة أسماء تنسيق متعددة الأحرف.register_printf_function()

تتضمن بعض التطبيقات (مثل خادم Apache HTTP ) دالة مشابهة لدالة printf، وتُدمج فيها امتدادات. مع ذلك، تميل جميع هذه التطبيقات إلى مواجهة نفس المشاكل التي register_printf_function()تواجهها التطبيقات الأخرى.

تدعم دالة نواة لينكسprintk عدة طرق لعرض هياكل النواة باستخدام المواصفات العامة، وذلك بإضافة أحرف تنسيق إضافية. [ 21 ] على سبيل المثال، تطبع عنوان IPv4 بصيغة عشرية منقطة. يتيح هذا التحقق الثابت من سلسلة التنسيق (للجزء ) على حساب التوافق الكامل مع دالة printf العادية.%p%pI4%p

نقاط الضعف

هجوم سلسلة التنسيق

يتم تجاهل وسائط القيمة الزائدة، ولكن إذا احتوى نص التنسيق على عدد من مُحدِّدات التنسيق يفوق عدد وسائط القيمة المُمرَّرة، فسيكون السلوك غير مُحدَّد. بالنسبة لبعض مُترجمات لغة C، يؤدي وجود مُحدِّد تنسيق إضافي إلى استهلاك قيمة حتى في حال عدم وجود قيمة، مما يسمح بهجوم نص التنسيق . عمومًا، في لغة C، تُمرَّر الوسائط على المكدس . إذا تم تمرير عدد قليل جدًا من الوسائط، فقد تتمكن دالة printf من القراءة بعد نهاية إطار المكدس، مما يسمح للمهاجم بقراءة المكدس.

تقوم بعض المترجمات، مثل مجموعة مترجمات جنو ، بفحص سلاسل التنسيق الخاصة بالدوال الشبيهة بـ printf بشكل ثابت، وتُصدر تحذيرات بشأن المشاكل (عند استخدام العلامات أو ). كما يُصدر GCC تحذيرات بشأن الدوال المُعرَّفة من قِبل المستخدم والتي تُشبه printf إذا تم تطبيق "تنسيق" غير قياسي على الدالة.-Wall-Wformat__attribute__

استغلال سلسلة التنسيق غير المتحكم بها

غالبًا ما تكون سلسلة التنسيق عبارة عن سلسلة نصية حرفية ، مما يسمح بالتحليل الثابت لاستدعاء الدالة. مع ذلك، يمكن أن تكون سلسلة التنسيق قيمة لمتغير ، مما يسمح بالتنسيق الديناميكي، ولكنه يُعرّض النظام أيضًا لثغرة أمنية تُعرف باستغلال سلسلة التنسيق غير المُتحكّم بها .

كتابة الذاكرة

على الرغم من أنها دالة إخراج ظاهريًا، إلا printfأنها تسمح بالكتابة إلى موقع ذاكرة محدد بواسطة وسيط عبر . يمكن استخدام هذه الوظيفة لهجمات حقن التعليمات البرمجية دون انتهاك سلامة تدفق التحكم . [ 22 ]%n

يُؤدي مُحدِّد التنسيق أيضًا إلى جعل البرنامج كاملًا تورينجيًا عن طريق الخطأ حتى مع مجموعة وسائط سليمة التكوين. [ 22 ] لعبة إكس أو مكتوبة بسلسلة التنسيق هي الفائزة في مسابقة IOCCC السابعة والعشرين . [ 23 ]%nprintf

عائلة

تتضمن المتغيرات printfفي مكتبة C القياسية ما يلي: fprintfإخراج البيانات إلى ملف بدلاً من الإخراج القياسي.

sprintfيكتب إلى مخزن مؤقت للسلاسل النصية بدلاً من الإخراج القياسي.

snprintfيوفر مستوى من الأمان sprintfلأن المتصل يوفر طولًا n وهو طول مخزن الإخراج بالبايت (بما في ذلك مساحة لحرف null اللاحق).

asprintfتُوفّر هذه الدالة الأمان من خلال قبول وسيطة سلسلة نصية ( ) char**. تقوم الدالة بتخصيص مخزن مؤقت بحجم كافٍ لاحتواء النص المنسق، ثم تُخرج المخزن المؤقت عبر هذه الوسيطة.

لكل دالة من دوال هذه العائلة، بما في ذلك دالة printf، يوجد أيضًا شكل بديل يقبل va_listوسيطًا واحدًا بدلًا من قائمة متغيرة من الوسائط. عادةً ما تبدأ هذه الأشكال البديلة بالحرف "v". على سبيل المثال: vprintf, vfprintf, vsprintf.

بشكل عام، تُرجع الدوال الشبيهة بـ printf عدد البايتات المُخرجة أو -1 للإشارة إلى الفشل. [ 24 ]

سياقات أخرى

تتضمن القائمة التالية لغات برمجة بارزة توفر (مباشرةً أو عبر مكتبة قياسية) وظائف مماثلة أو مشابهة لوظائف printf في لغة C. ويُستثنى من ذلك اللغات التي تستخدم سلاسل تنسيق تختلف عن الأسلوب المذكور في هذه المقالة (مثل AMPL و Elixir )، واللغات التي ترث تنفيذها من آلة جافا الافتراضية (JVM) أو بيئة أخرى (مثل Clojure و Scala )، واللغات التي لا تملك تنفيذًا أصليًا قياسيًا لوظيفة printf ولكنها تحتوي على مكتبات خارجية تحاكي سلوكها (مثل JavaScript ).

انظر أيضاً

  • برنامج "مرحباً بالعالم!" برنامج مثال أساسي ظهر لأول مرة في كتاب "لغة البرمجة سي " (كتاب "كيه آند آر")، والذي يستخدم في مثال لغة سي دالة printf لإخراج الرسالة "مرحباً بالعالم!" 
  • دالة التنسيق (لغة Common Lisp) – دالة في لغة Common Lisp تُنتج نصًا منسقًا 
  • مكتبة C القياسية – مكتبة قياسية للغة البرمجة C 
  • هجوم سلسلة التنسيق – نوع من أنواع الثغرات الأمنية في البرامج : صفحات تعرض أوصافًا مختصرة لأهداف إعادة التوجيه 
  • الإدخال/الإخراج (C++) – وظائف الإدخال/الإخراج في لغة C++ ضمن المكتبة القياسية. صفحات تعرض أوصافًا مختصرة لأهداف إعادة التوجيه. 
  • تصحيح أخطاء printf – إصلاح العيوب في نظام هندسي. صفحات تعرض أوصافًا مختصرة لأهداف إعادة التوجيه. 
  • printf (يونكس) – أمر سطر الأوامر لتنسيق النصوص وإخراجها؛ يشبه دالة مكتبة printf() 
  • printk – دالة شبيهة بدالة printf لنواة لينكس 
  • دالة scanf – مُعامل تحكم يُستخدم في لغات البرمجة 
  • استيفاء السلاسل النصية – استبدال العناصر النائبة في سلسلة نصية بالقيم 

ملحوظات

  1. وفقًا لدليل فورتران لعام 1956 [ 1 ] ،PRINTيطبع الأمر على الطابعة المتصلة . كما يقدم الدليل أمرًاآخر يستخدم العبارة نفسهاللكتابة على وحدة الشريط .WRITE OUTPUTTAPEFORMAT

مراجع

  1. 1 2 باكوس، جون وارنر ؛ بيبر، آر جيه؛ بيست، شيلدون إف؛ غولدبيرغ، ريتشارد؛ هيريك، هارلان إل؛ هيوز، آر إيه؛ ميتشل، إل بي؛ نيلسون، روبرت إيه؛ نوت، روي ؛ ساير، ديفيد ؛ شيريدان، بيتر بي؛ ستيرن، هارولد؛ زيلر، إيرفينغ (15 أكتوبر 1956). ساير، ديفيد (محرر). نظام الترميز التلقائي للغة فورتران لجهاز IBM 704 EDPM: دليل مرجعي للمبرمج (PDF) . نيويورك، الولايات المتحدة الأمريكية: قسم العلوم التطبيقية وقسم أبحاث البرمجة، شركة آي بي إم . الصفحات 26-30 . مؤرشف (PDF) من الأصل في 4 يوليو 2022. تم الاسترجاع في 4 يوليو 2022 . (صفحتان + 51 صفحة + صفحة واحدة)
  2. "BCPL" . cl.cam.ac.uk. تم الاطلاع عليه بتاريخ 19 مارس 2018 .
  3. ريتشاردز، مارتن؛ ويتبي-ستريفنز، كولين (1979). BCPL - اللغة ومترجمها . مطبعة جامعة كامبريدج. ص 50 . 
  4. "هجوم سلسلة التنسيق" .
  5. ماكيلروي، دكتور في الطب (1987). قارئ أبحاث يونكس: مقتطفات مشروحة من دليل المبرمج، 1971-1986 (ملف PDF) (تقرير فني). مختبرات بيل. 139.
  6. "printf (4.3+Reno BSD)" . man.freebsd.org . تم الاطلاع عليه في 1 أبريل 2024 .
  7. "المعلمات الموضعية" . tldp.org . تم الاطلاع عليه بتاريخ 16 ديسمبر 2025 .
  8. "Class PrintStream" . docs.oracle.com . تم الاطلاع عليه بتاريخ 13 سبتمبر 2025 .
  9. "3.8 خيارات لطلب أو كتم التحذيرات" . دليل GCC 14.2 . مؤسسة البرمجيات الحرة . 2024. تم الاطلاع عليه بتاريخ 12 فبراير 2025 .
  10. ستروستروب، بيارن (مارس 1993). "تاريخ لغة C++: 1979-1991" . نشرة ACM SIGPLAN . 28 (3). رابطة آلات الحوسبة : 271-297 . doi : 10.1145/155360.155375 . ISSN 0362-1340 . 
  11. 1 2 3 كولير، سبنسر (ديسمبر 2021). "تنسيق النصوص في لغة C++20: مقدمة" . Overload . 29 (166). المملكة المتحدة: ACCU : 9-21 . ISSN 1354-3172 . Wikidata Q140407206 .  
  12. بانسيلا، ماريوس (2020). "العمل مع الأرقام والسلاسل النصية" . كتاب طبخ برمجة C++ الحديثة ( الطبعة الثانية). Packt. ISBN  978-1-8002-0620-5.
  13. زفيروفيتش، فيكتور (16 يوليو 2019). "تنسيق النصوص" . أوراق لجنة معايير لغة C++. المعايير المفتوحة.
  14. كوسورم، دانيال (نوفمبر 2024). "الإدخال/الإخراج المنسق" . برمجة STL العملية بلغة C++ . بيركلي، كاليفورنيا: أبريس . الصفحات 63-103 . ISBN  979-8-8688-0774-9.
  15. "طباعة آمنة" .
  16. كوسونين، إي.؛ زفيروفيتش، ف. (15 أكتوبر 2024). "P1729R5: تحليل النصوص" . أوراق لجنة معايير لغة C++. المعايير المفتوحة.
  17. "printf" . cplusplus.com . تم الاطلاع عليه بتاريخ 10 يونيو 2020 .
  18. "7.19.6.1". ISO/IEC 9899:1999(E): لغات البرمجة - لغة C (تقرير فني). ISO / IEC . 1999. الفقرة 7.
  19. ^ ينس جوستيدت (15 أكتوبر 2024). “وظائف مكتبة C”. الحديثة ج . إينريا. ص. 120. ردمك  9781617295812.
  20. شيلدت، هـ.؛ كوارد، د. (2024). "java.util الجزء 2: المزيد من فئات الأدوات المساعدة". في ريتر، س. (محرر). جافا: المرجع الكامل (الطبعة 13 ). ماكجرو هيل. ص 667-726 . ISBN   978-1-265-05843-2.
  21. دانلاب، راندي؛ موراي، أندرو (بدون تاريخ). "كيفية ضبط مُحدِّدات تنسيق printk بشكل صحيح". وثائق نواة لينكس (تقرير). مؤسسة لينكس . مؤرشف من الأصل في 6 فبراير 2025. تم الاطلاع عليه في 12 فبراير 2025 .
  22. 1 2 كارليني، ن.؛ باريسي، أ.؛ باير، م.؛ فاغنر، د.؛ غروس، ت. ر. (12 أغسطس 2015). "انحناء تدفق التحكم: حول فعالية سلامة تدفق التحكم" (ملف PDF) . وقائع المؤتمر الرابع والعشرين لندوة الأمن التابعة لـ USENIX . SEC'15. واشنطن العاصمة: USENIX . الصفحات 161-176 . ISBN  978-1-931971-23-2. S2CID 2165728 . 
  23. كارليني، نيكولاس (2020). "آلة printf" . المسابقة الدولية لشفرة C المبهمة . الحكام: ليونيد أ. بروخيس، لاندون كورت نول. لاندون كورت نول . تاريخ الاسترجاع: 12 فبراير 2025 .
  24. كيريسك، مايكل (2 فبراير 2025). "sprintf(3) — صفحة دليل لينكس" . man7.org . تم الاطلاع عليه في 19 مارس 2025 .
  25. "POSIX awk، عبارات الإخراج". المواصفات الأساسية لمجموعة Open Group، الإصدار 7. pubs.opengroup.org ( تقرير فني) ( طبعة 2018). مجموعة Open Group . تم الاطلاع عليه بتاريخ 29 مايو 2022 . 
  26. "مكتبة Printf القياسية" . دليل لغة جوليا . تم الاطلاع عليه بتاريخ 22 فبراير 2021 .
  27. "أنواع البيانات المدمجة: تنسيق السلاسل النصية" ، مكتبة بايثون القياسية ، مؤسسة برمجيات بايثون ، تم الاطلاع عليه بتاريخ 24 فبراير 2021printf
  28. "دالة printf() المدمجة في SQLite" . sqlite.org . تم الاطلاع عليه بتاريخ 24 نوفمبر 2025 .