الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

الكتابة إلى Standard Error Output

مغلق
بدأه هاني الأتاسي في 29 يونيو 2001 · 18 رد · 1,887 مشاهدة · في لغة Delphi
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

السلام عليكم ،

بصراحة هذا السؤال شوية باسكال على شوية دلفة ... كلنا نعلم أنه في الباسكال أو ال Console Application فإنه يوجد ملفين Input و Output ولكن في الحقيقة يوجد ملف آخر (في السي هو StdErr) ... توجد توابع API عديدة للكتابة إلى أي من هذه الملفات .. لكن سؤالي عن كيفية استخدام التابع Write للكتبة على StdErr ... أو يمكن أن أصيغ السؤال بطريقة أخرى ..

يوجد نوعين الملفات File و Text في ال Pascal ويمكن أن أحصل على Handle ل StdErr من الويندوز ولكن لا أعرف طريقة تحويل هذا الHandle إلى نوع ملفات ال Pascal حتى يمكن استخدامها في Write أو Writeln ... ؟؟؟

وشكرا :)

Coding on the Cloud and for the Cloud!

My Blog

#2

السلام عليكم ،،

و الله لي زمن عن الباسكال و الدلفي ، لكن باعطيك اللي عندي مع اني ما فهمتك مرة ، stderror هي ال screen ?? عموما استخدمها كالتالي :

ضع الجملة اللي تبي تنفذها داخل بلوك try ... except

بعدين writelen(the name of the file,'here but what you want

with xx', errdescription

اتمنى اكون افدتك ،،

#3

بسم الله الرحمن الرحيم

اهلاً بك يااخ هاني وانت كذلك يااخ neoo

في المنتدى

ونتشرف بمشاركتكم معنا

بس يااخ هاني ممكن لو توضح سؤالك شوي

لأني مافهمت عليك :)

وتقبلوا اطيب تحياتي اخوكم SUM

#4

اخي هاني .

ادا ممكن تكتب لنا الطريقة الي تمسك بيها في الهاندل حتى نبين طريقة استخدامها في الباسكال .

#5

آسف إن كنت كتبت السؤال على عجلة ....

حسنا خليني أتكلم عن برامج الدوس أو ال Console Aplication كلنا يعرف أنه هناك خرج إلى الشاشة وهناك دخل من الكيبورد في الباسكال كان الخرج إلى الشاشة يمثله الملف Output والدخل يمثله الملف Input . وهما عبارة عن Buffer في الذاكرة لا أكثر . في الواقع المفروض يوجد خرج ثالث وهو أيضا للشاشة ولكنه مختص بطباعة رسائل الخطأ ... وخرج الشاشة العادي مختلف عن خرج الأخطاء لأن كل منهما في ملف منفصل حتى ولو كانا يطبعان على الشاشة ، فمثلا ليكن لدينا البرنامج Test.EXE الذي يطبع على الشاشة عن طريق الملف Output و ملف خرج الأخطاء القياسي . فحين تشغيل البرنامح فإنك تجد جميع الرسائل والأخطاء مطبوعة على الشاشة ولكن هناك خاصية للدوس من أجل تحويل هذه الملفات (Input و Output و StdErr) إلى ملفات أو أجهزة أخرى غير الشاشة والكيبورد ، فمثلا ..

Test.exe 1>myfile.txt فإن أي شئ يكتب إلى الملف Output فإنه يحول بشكل أوتوماتيكي إلى الملف myfile.txt ..

Test.exe 2>myfile.txt يعني أي شئ يكتب إلى StdErr فإنه يحول إلى هذا الملف ..

Test.exe 0

الآن إن الملف stderr هو من الملفات القياسية المعرفة في السي بالإضافة إلى stdin المكافئ ل Input و stdout المكافئ ل Output .. ولكني بصراحة لم أجد مكافئ ل stderr في ال Pascal على حد علمي وبحثي !! ولكن ما علينا لأن ما هو هذا السؤال .

الآن كما شرحت في السابق فإن بعض البرامج في الدوس تقوم باستدعاء برنامجك (Console Application) مع إضافة اسم الملف وعلامة أكبر والرقم 2.. لأن ذاك البرنامج يريد تسجيل جميع رسائل الأخطاء الصادرة عن برنامجك ومعالجتها ، ومثال على تلك البرامج هي محررات Editors التي يكتب فيها البرامج التي تحتاج إلى برنامج خارجي من أجل عملية ال Compiler فبرنامج الCompiler يقوم بطباعة الأخطاء إلى stderr وبرنامج المحرر يكون قد قام بعملية تحويل ال stderr إلى ملفه الخاص الذي يقوم بقرائته وعرضه ..

بالنسبة للوندوز أو Console Application فإنه يوجد العديد من توابع ال API التي تسمح لك بالتعامل مع تلك الملفات الثلاث والذي يفيدنا هنا من أجل السؤال هو التابع GetStdHandle ويؤخذ بارمتر يمكن أن تكون قيمته أحد القيم التالية :

STD_INPUT_HANDLE

STD_OUTPUT_HANDLE

STD_ERROR_HANDLE

هذا التابع يرجع Handle يمكن التعامل مع هذا المقبض كما لو أنه Handle ل ملف أي يمكن استخدام التابع WriteFile و WriteConsole وغيرها ..

بالامكان استخدام توابع ال API لأداء الغرض في Console Application ولكن هذا يحتاج إلى الكثير من الكود وكتابة توابع مثلا WriteErrLn التي تنفذ عدد من تعليمات ال API . الحل الآخر الذي أنا أسئل عنه وهو أنا أريد استخدام التوابع المحجوزة Write و WriteLn مع تحديد ملف .. كلنا يعلم أن هذه التوابع لا تقبل إلا ملفات من نوع File و Text ...

السؤال هو : أريد تحويا ذاك ال Handle إلى نوع ملف Text حتى يمكن استخدامه في Write أو Writeln؟؟؟؟؟

وعلى فكرة حتى بعض محررات ال GUI أي التي تعمل في الويندوز مثل MultiEdit وهي محررات للعديد من اللغات مثل ++C و Pascal و Html و ... و فإنها عندما تستدعي المترجم من أجل عملية الترجمة فإنها تقوم بقرائة الخرج على ملف stderr مباشرة من أجل عرضه ...

بصراحة أن أكثر المترجمات الشهيرة ومن ضمنهم ++VC فإن البيئة تقوم بتنفيذ برنامح Console وطبعا مع إخفاء نافذة الدوس هذا البرنامج هو المترجم أو Command Line Compiler الملف الذي يأخذ أوامر عملية الترجمة عن طريق سطر الأوامر مثل اسم الملف وغيره .. فتجد أن ++VC يقوم بكتابة ما يكتبه ذاك المترجم في نافذة في واجهة الويندوز وذلك بأن يصنع pipe (يمكن أن تقول ملف ولكن ميزته أن أي شئ يكتب في الملف فإن الطرف الآخر يستقبله مباشرة - وأعتقد أن هذا مأخوذ من نظام ال Unix) لكي تقرأ جميع نتائج الخرج في واجهة الفيجوال سي ....

إذا كنت محمل الفيجوال سي++ فقم بالتجربة التالية ..

إن المترجم الأساسي في فيجوال سي هو الملف MC.EXE وتجده في الدليل bin . هذا الملف هو برنامج Console Application . قم بالتجربة ونفذه ولكن وأنت في نافذة الدوس في الويندوز (DOS Shell أو Command Prompt) ، تلاحظ ظهور العديد من الكتابات . وفي مثل هذه الحالات تقوم بتنفيذه من جديد مع إضافة more كالتالي :

MC.exe | MORE والتي من المفروض أن تطبع Press any key to continue عند انتهاء كل صفحة ، ولكنها لم تعمل هنا لماذا ؟ لأن البرنامج MC لم يخرج الكتابات على الملف stdout أو Output .

جرب :

MC.exe >myfile.txt أو MC.exe 1>myfile.exe من دون أي جدوى ..

ولكن إذا جربت ::

MC.EXE 2>myfile.exe فإنك سوف تجد أن الخرج كتب في الملف myfile.txt ويمكنك فتحه وقرائته هذا يعني أن MC يكتب كل رسائله في الملف stderr عوضا عن stdout .. وهذا متعارف عليه لأنه لو أتى أي Editor وقام باستدعاء ال برنامج MC فهذا الEditor يعرف من وين يأخذ معلوماته ...

أرجو أن تكونو استفدتم فأفيدوني ... :)

Coding on the Cloud and for the Cloud!

My Blog

#6

بسم الله الرحمن الرحيم

اخي العزيز هاني

الآن فهمت عليك وارجوا ان يكون فهمي لسؤالك صحيحاً:)

فكما تعلم انه يوجد تصيرح في الدلفي يسمى variant

ووضيفته انه يمشي مع اي قيمه تبغا :)

يعني اذا عجزت ان تجد شي مقابل شي تستطيع استخدام variant بجيث تقوم بالتصريح عنها في var

وطبعاً الجواب هذا هو جواب لأسئلتك جميعاً

واليك هذه الامثله:

1)هذا مثال على سؤالك الأول (( قيمه مساويه ل stderr(طبعاً هذا مثال توضيحي لأستخدام variant ) ))

var

v:variant;

begin

v:=stderr;

------------

2) هذا مثال على سؤالك الثاني

var

H:THandle;

V:variant;

begin

V:=H;

Write(v);

------------------

وتقبل اطيب تحياتي اخوك SUM

#7

أخ SUM أرجو أن تجرب طريقتك فأنا أشك في عملها فعلى كل الأجوال فإن variant في هذه الحالة سوف تحمل Handle لملف الويندوز وليس لملف Pascal ... أنا لا أستطيع تجربتها حتى يوم الاثنسن فأرجو أن تجربها وتخبرني ....

وشكرا للمساعدة

Coding on the Cloud and for the Cloud!

My Blog

#8

انا راح احاول اجربها , لكن وين ممكن القى stderr يعني في اي ملف من ملفات use , و الا هو معرف مباشرة في الدلفي .

اقصد انه متلا في لغة السي لازم نضع

< include

لكن في دلفي نستخدم جملة use , لكن شو اسم الملف الي مفروض يكون بداخله تعريف stderr

وشكرا

#9

stderr ليس ملف عام هو بس اسم ومعرف في الملف stdio.h في السي ويملك ال Handle رقم 2 ولكن في الدوس فقط كما شرحت ... أنا لا أريد استخدام الاسم stderr لأنه غير معرف في ال Pascal بل أريد استخدام GetStdHandle من الويندوز وتحويل ال Handle إلى نوع File أو Text ..

Coding on the Cloud and for the Cloud!

My Blog

#10

بسم الله الرحمن الرحيم

اخي العزيز هاني

لقد قمت بتجربت العملية (( يعني اقرا Handle ك string او اي شي آخر ))

وقد نجحت العملية 100%

طبعاً لكي لايكون هناك لبس بالعملية

قمت بعمل كود وقمت بوضعه على هذه الوصلة

http://www.8op.com/sum/Handle.zip

طبعاً البرنامج الي في الكود يقوم بقرائة Handle التابعة لل Application ومن ثم يقوم بأظافتها في محرر النصوص وطبعاً قمت بوضع زر آخر يمكنك من حفظ النص في ملف خارجي

وانا قمت بعمل المثال لتوضيح كيفية تحويل Handle

طبعاً الكود مسويه انا بالدلفي

وتقبل اطيب تحياتي اخوك SUM

#11

يعطيك العافية أخي SUM ..

سوف أجرب هذه الطريقة وأردلك خبر يوم الاثنين ..

Coding on the Cloud and for the Cloud!

My Blog

#12

اخي الغالي سم , ياريت تقدر تغير الموقع الى تحط بيه الكود لان

الموقع http://www.8op.com ضعيف جدا جدا , ولم استطع تنزيل اي شي منه , من قبل وحتى هده المرة .

وشكرا

#13

اخي العزيز Madi

الصحيح اني معك في كلامك

بس انا مابيدي حيله

مالقيت اي شركة مساحتها الأستضافيه زينه

واذا كنت تعرف شركة خدمتها زينه فأخبرني

وتقبل تحياتي اخوك SUM

#14

أخ SUM آسف بس ماهذا الذي كنت أريده ،، الظاهر أنك مافهمتني منيح ..

أنا قمت بتنزيل Delphi 6 وقمت بتجريب التالي ..

التابع GetStdHandle يرجع فيa الدلفي THandle فكيف وعلى أي أساس سوف أمرره إلى Writeln كملف ؟؟!؟!؟! حتى ولو تمت العملية عبر Variant كما تقول .. ففي الحالتين سوف تتم عملية الترجمة بنجاح ولكن حين تتأتي دور العملية Writeln تظهر رسلة خطأ Error i/o ....

أنا أريد طريقة عملية وعلمية في تحويل Handle الوينجوز أو ال THandleإلى ملف من نوع Text ...

وشكرا سلفا على تعبكم معانا ..

Coding on the Cloud and for the Cloud!

My Blog

#15

بسم الله الرحمن الرحيم

اعذرني يااخ هاني

على فهمي الخاطي

طبعاً على مااذكر ان فيه محولات في الباسكال

يعني مثل هذه (( strtoint و inttostr و ....))

سأبحث لك عن التي تحول لك قيمت Handle الى string.

وسأخبرك عندما اجدها

وتقبل اطيب تحياتي اخوك SUM

#16

أخ SUM أرجو أن تفتح مخك معاي ...

أن لا أريد تحوبل هاندل ملف الويندوز إلى String بل إلى ملف من نوع Text ، فهاندل الملف يحول إلى ملف ولكن بشكل آخر.. أرجو أن تبحث في ملفات الدلفي عن المتحول Output وترى هو من أي نوع .. إن الملفين File و Text هما من أنواع الملفات القياسية في الباسكال ...

أشكرك أخ SUM على سهرك معي ..

Coding on the Cloud and for the Cloud!

My Blog

#17

اخي العزيز هاني

ممكن لو تشرح وضيفة برنامجك

علشان اقدر افهمك متطلباتك زين

ولايكون هناك لبس في العملية

وتقبل اطيب تحياتي اخوك SUM

#18

بسم الله الرحمن الرحيم

اخي العزيز هاني

لو وجدت طريقة التحويل Handle الى string

وهي

Flaottostr(Handle);

اما تحويل Handle الى Text فلم ابحث عنها

على العموم يمكنك مراجعة هذه الصفحة

http://www.delphinow.com/sub.asp?catID=8

وتقبل اطيب تحياتي اخوك SUM

#19

أخي SUM .. أشكرك ولكن ..

اذا كنت تريد أن تقرأ فيمة الHandle كString لا تستخدم FloatToStr بل يمكن أن تستخدم IntToHex أو IntToStr ... ولكن هذا لا أريده ..

بالنسبة لتحويل ال Handle إلى ملف Text فيبدو أن هذا مستحيل في الباسكال والحل الوحيد كان أن قمت بعمل روتين سميته WriteLnErr يستعمل توابع الAPI من أجل الكتابة على StdErr ..

وشكرا

Coding on the Cloud and for the Cloud!

My Blog

هذا الموضوع مغلق.

مواضيع مشابهة