سؤال

في بيئة C/Unix التي أعمل فيها، أرى بعض المطورين يستخدمون __progname بدلاً من argv[0] لرسائل الاستخدامهل هناك بعض المزايا لهذا؟ما الفرق بين __progname و argv[0].هل هو محمول؟

هل كانت مفيدة؟

المحلول

و__progname غير القياسية، وبالتالي لا المحمولة، ويفضل argv[0]. أفترض __progname يمكن بحث مورد سلسلة للحصول على اسم الذي لا يعتمد على اسم الملف الذي يدير هذه القوة ما. ولكن سيعطي argv[0] لك الاسم الذي <م> في الواقع يدير هذه القوة ما الذي أود أن تجد أكثر فائدة.

نصائح أخرى

وعن طريق __progname يسمح لك لتغيير محتويات مجموعة argv[] مع الحفاظ على اسم البرنامج. بعض الأدوات المشتركة مثل getopt() تعديل argv[] لأنها معالجة الحجج.

لنقل، يمكنك strcopy argv[0] إلى عازلة progname الخاصة بك عندما يبدأ البرنامج.

هناك أيضًا امتداد GNU لهذا، بحيث يمكن للمرء الوصول إلى اسم استدعاء البرنامج من خارج main() دون حفظه يدويًا.ومع ذلك، قد يكون من الأفضل القيام بذلك يدويًا؛مما يجعلها محمولة بدلاً من الاعتماد على امتداد جنو.ومع ذلك، فإنني أقدم هنا مقتطفًا من الوثائق المتاحة.

من دليل مكتبة GNU C على الإنترنت (تم الوصول إليه اليوم):

"تم تصميم العديد من البرامج التي لا تقرأ المدخلات من الجهاز الطرفي للخروج في حالة فشل أي استدعاء للنظام.وفقًا للاتفاقية، يجب أن تبدأ رسالة الخطأ الصادرة عن مثل هذا البرنامج باسم البرنامج، بدون أدلة.يمكنك العثور على هذا الاسم في المتغير program_invocation_short_name;يتم تخزين اسم الملف الكامل المتغير program_invocation_name.

  • عامل:شار * Program_invocation_nameقيمة هذا المتغير هي الاسم الذي تم استخدامه لاستدعاء البرنامج قيد التشغيل في العملية الحالية.إنه نفس الشيء argv[0].لاحظ أن هذا ليس بالضرورة اسم ملف مفيد؛في كثير من الأحيان لا يحتوي على أسماء الدليل.

  • عامل:شار * Program_invocation_short_nameقيمة هذا المتغير هي الاسم الذي تم استخدامه لاستدعاء البرنامج قيد التشغيل في العملية الحالية، مع إزالة أسماء الدلائل.(أي أنه مثله program_invocation_name ناقص كل شيء حتى الشرطة المائلة الأخيرة، إن وجدت.)

يقوم رمز تهيئة المكتبة بإعداد كلا هذين المتغيرين قبل استدعاء main.

ملاحظة قابلية النقل: هذان المتغيران هما امتدادات جنو.إذا كنت تريد أن يعمل برنامجك مع مكتبات غير تابعة لـ GNU، فيجب عليك حفظ قيمة argv[0] بشكل رئيسي، ثم قم بإزالة أسماء الدليل بنفسك.لقد أضفنا هذه الامتدادات لنجعل من الممكن كتابة إجراءات فرعية قائمة بذاتها للإبلاغ عن الأخطاء والتي لا تتطلب تعاونًا صريحًا من الجانب الرئيسي."

وأرى اثنين على الأقل من المشاكل المحتملة مع ARGV [0].

أولا، ARGV [0] أو ARGV نفسها قد تكون فارغة إذا كان execve () المتصل الشر أو الإهمال بما فيه الكفاية. داعيا execve ( "foobar"، NULL، NULL) عادة ما تكون وسيلة سهلة وممتعة لإثبات مدى مبرمج ثقة متاحة له ليس sig11 إثبات.

ويجب أن يلاحظ أيضا أنه لن يتم تعريفها ARGV خارج الرئيسية () في حين يعرف __progname عادة متغير عمومي يمكنك استخدامها من خلال استخدامك وظيفة () أو حتى قبل الرئيسي () ويسمى (مثل غير القياسية الصانعين مجلس التعاون الخليجي).

وانها BSDism، وبالتأكيد ليست المحمولة.

و__ progname هو مجرد ARGV [0]، والأمثلة في ردود أخرى هنا تظهر نقاط الضعف في استخدامه. وإن لم يكن المحمولة سواء، وأنا باستخدام readlink على / إجراءات / الذات / اكس (لينكس، الروبوت)، وقراءة محتويات / إجراءات / الذات / exefile (QNX).

إذا تم تشغيل البرنامج باستخدام، على سبيل المثال، ارتباط رمزي، ARGV [0] سوف تحتوي على اسم هذا الرابط.

وأنا على التخمين بأن __progname سوف تحتوي على اسم ملف البرنامج الفعلي.

في أي حال، يعرف ARGV [0] وفق المعايير C. __progname ليست كذلك.

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