c - عمل اشارة مرجعية في الوورد 2010 معنى



لماذا لا تتم طباعة printf بعد المكالمة ما لم يكن السطر الجديد في سلسلة التنسيق؟ (6)

لماذا لا تتم printf بعد المكالمة ما لم يكن السطر الجديد في سلسلة التنسيق؟ هل هذا السلوك POSIX؟ كيف يمكنني الحصول على printf فورًا في كل مرة؟

https://src-bin.com


Answer #1

إلى تدفق مباشرة fflush(stdout) الدعوة fflush(stdout) أو fflush(NULL) (يعني NULL مسح كل شيء).


Answer #2

استخدم setbuf(stdout, NULL); لتعطيل التخزين المؤقت.


Answer #3

لا ، إنه ليس سلوك POSIX ، إنه سلوك ISO (جيد ، إنه سلوك POSIX لكن فقط بقدر ما يتوافق مع ISO).

يكون المخرج القياسي مخزّنًا إذا تم اكتشافه للإشارة إلى جهاز تفاعلي ، وإلا فإنه يتم تخزينه مؤقتًا بشكل كامل. لذلك هناك حالات لا تتم فيها عملية printf ، حتى لو حصلت على سطر جديد لإرساله ، مثل:

myprog >myfile.txt

هذا الأمر منطقي للكفاءة حيث أنه إذا كنت تتفاعل مع مستخدم ، فمن المحتمل أن يرغب في رؤية كل سطر. إذا كنت ترسل المخرجات إلى ملف ، فمن المرجح أنه لا يوجد مستخدم في الطرف الآخر (على الرغم من أنه ليس مستحيلاً ، فقد يكون من الممكن أن يتخلص من الملف). الآن يمكنك أن تجادل بأن المستخدم يريد أن يرى كل شخصية ولكن هناك مشكلتان في ذلك.

الأول هو أنها ليست فعالة للغاية. والثاني هو أن مهمة ANSI C الأصلية كانت في الأساس تدوين السلوك الحالي ، بدلاً من ابتكار سلوك جديد ، وتم اتخاذ قرارات التصميم تلك قبل أن تبدأ ANSI بالعملية بفترة طويلة. حتى أن ISO في الوقت الحاضر تتعامل بحذر شديد عند تغيير القواعد الموجودة في المعايير.

فيما يتعلق بكيفية التعامل مع ذلك ، إذا قمت fflush (stdout) بعد كل مكالمة إخراج تريد رؤيتها على الفور ، فإن ذلك سيحل المشكلة.

بدلاً من ذلك ، يمكنك استخدام setvbuf قبل التشغيل على stdout ، لتعيينه إلى unbuffered ولن تقلق بشأن إضافة جميع هذه الخطوط fflush إلى التعليمات البرمجية الخاصة بك:

setvbuf (stdout, NULL, _IONBF, BUFSIZ);

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

القسم ISO C99 7.19.3/3 هو البت المعني:

عندما يكون الدفق غير محمي ، يُقصد من الأحرف الظهور من المصدر أو الوجهة في أقرب وقت ممكن. وإلا فقد يتم تجميع الأحرف ونقلها من أو إلى بيئة المضيف ككتلة.

عندما يكون الدفق مخزناً بالكامل ، يُقصد من الأحرف أن تنتقل إلى أو من بيئة المضيف ككتلة عند ملء مخزن مؤقت.

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

علاوة على ذلك ، يقصد بالأحرف أن يتم إرسالها ككتلة إلى بيئة المضيف عندما يتم ملء المخزن المؤقت ، أو عند طلب الإدخال على تيار غير محمي ، أو عند طلب الإدخال على دفق خطي مخزن يتطلب نقل الأحرف من البيئة المضيفة .

يتم تعريف دعم هذه الخصائص ، وقد تتأثر من خلال وظائف setbuf و setvbuf .



Answer #5

يتم تخزين المخزن المؤقت ، لذلك سيتم إخراج فقط بعد طباعة سطر جديد.

للحصول على الإخراج الفوري ، إما:

  1. الطباعة إلى stderr.
  2. جعل stdout unbuffered.

Answer #6

يتم تخزين دفق stdout ، لذلك سيتم فقط عرض ما في المخزن المؤقت بعد أن يصل إلى سطر جديد (أو عندما يُطلب منه). لديك بعض الخيارات للطباعة على الفور:

الطباعة إلى stderr بدلاً من ذلك باستخدام fprintf :

fprintf(stderr, "I will be printed immediately");

تدفق stdout كلما كنت في حاجة إليها باستخدام fflush :

printf("Buffered, will be flushed");
fflush(stdout); // Will now print everything in the stdout buffer

تعديل : من تعليق Andy Ross أدناه ، يمكنك أيضًا تعطيل التخزين المؤقت على stdout باستخدام setbuf :

setbuf(stdout, NULL);




printf