اذهب إلى المحتوى

التعامل مع المحارف وضبط إعدادات التوطين localization في لغة سي C


Naser Dakhel

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

التعامل مع المحارف

هناك مجموعةٌ متنوعةٌ من الدوال تهدف لفحص وربط mapping المحارف، إذ تسمح لك دوال الفحص test functions -التي سنناقشها أولًا- بفحص فيما إذا كان المحرف من نوع معين، مثل حرف أبجدي، أو حرف صغير أم كبير، أو محرف رقمي، أو محرف تحكّم control character، أو إشارة ترقيم، أو محرف قابل للطباعة أو لا، وهكذا. تُعيد دوال فحص المحرف قيمة عدد صحيح integer تساوي الصفر إذا لم يكن المحرف المُحدّد منتميًا إلى التصنيف المذكور، أو قيمة غير صفرية عدا ذلك، ويأخذ هذا النوع من الدوال وسيطًا ذا قيمة عدد صحيح تُمثّل قيمته من نوع "unsigned char"، أو عدد صحيح ثابت قيمته "EOF" مثل تلك القيمة المُعادة من دوال مشابهة، مثل getchar()‎، ونحصل على سلوك غير معرّف خارج هذه الحالات.

تعتمد هذه الدوال على إعدادات البرنامج المحلية:

محرف الطباعة printing character هو عضو من مجموعة المحارف المعرّفة بحسب التطبيق، ويشغل كل محرف طباعة موقع طباعة واحد، ومحرف التحكم control character هو عضو من مجموعة المحارف المعرفة بحسب التطبيق أيضًا إلا أن كل محرف منها ليس بمحرف طباعة. إذا استخدمنا مجموعة محارف معيار ASCII ‏‎7-bit، ستكون محارف الطباعة بين الفراغ (0x20) وتيلدا tilde‏ (0x7e)‏‎، بينما تكون محارف التحكم بين NUL (0x0‎)‎ و US (0x1f)‎ والمحرف DEL (0x7f)‎.

تجد أدناه ملخصًا يحتوي على جميع دوال فحص المحرف، ويجب تضمين ملف الترويسة <ctype.h> قبل استخدام أيّ منها.

  • دالة isalnum(int c)‎: تُعيد القيمة "True" إذا كان c محرفًا أبجديًا أو رقمًا؛ أي (isalpha(c)||isdigit(c)‎).
  • دالة isalpha(int c)‎: تُعيد القيمة "True" إذا كان هذا الشرط (isupper(c)||islower(c)‎) محققًا، كما أنها تُعيد القيمة True لمجموعة المحارف المُعرفة بحسب التطبيق التي لا تعيد القيمة True عند تمريرها على الدالة iscntrl أو isdigit أو ispunct أو isspace وتكون مجموعة المحارف الإضافية هذه فارغة في لغة سي المحلية.
  • دالة iscntrl(int c)‎: تُعيد القيمة True إذا كان المحرف محرف تحكم.
  • دالة isdigit(int c)‎: تُعيدالقيمة True إذا كان المحرف رقمًا عشريًا decimal.
  • دالة isgraph(int c)‎: تُعيد القيمة True إذا كان المحرف هو محرف طباعة عدا محرف المسافة الفارغة.
  • دالة islower(int c)‎: تُعيد القيمة True إذا كان المحرف محرفًا أبجديًا صغيرًا lower case، كما أنها محققة لمجموعة محارف معرفة حسب التطبيق لا تُعيد القيمة True لأي من الدالة iscntrl أو isdigit أو ispunct أو isspace، وتكون مجموعة المحارف الإضافية هذه فارغة في C المحلية.
  • دالة isprint(int c)‎: تُعيد القيمة True إذا كان المحرف محرف طباعة (متضمّنًا محرف المسافة الفارغة).
  • دالة ispunct(int c)‎: تُعيد القيمة True إذا كان المحرف محرف طباعة عدا محرف المسافة الفارغة أو المحارف التي تُعيد القيمة True في دالة isalnum.
  • دالة isspace(int c)‎: تُعيد القيمة True إذا كان المحرف محرف مسافة بيضاء (المحرف ' ' أو ‎\f أو ‎\n أو ‎\r أو ‎\t أو ‎\v)
  • دالة isupper(int c)‎: تُعيد القيمة True إذا كان المحرف محرف أبجديًا كبيرًا upper case، كما أنها محققة لمجموعة محارف معرفة حسب التطبيق لا تُعيد القيمة True لأي من الدالة iscntrl أو isdigit أو ispunct أو isspace، وتكون مجموعة المحارف الإضافية هذه فارغة في لغة سي المحلية.
  • دالة isxdigit(int c)‎: تُعيد القيمة True إذا كان المحرف رقم ستّ عشري صالح.

هناك دالتان إضافيتان تربطان المحارف من مجموعةٍ إلى أخرى، إذ تُعيد الدالة tolower محرفًا صغيرًا موافقًا لمحرف كبير مُرِّر لها، على سبيل المثال:

tolower('A') == 'a'

تُعيد الدالة tolower المحرف ذاته، إذا تلقّت أي محرف مُغاير للمحارف الأبجدية الكبيرة.

تربط الدالة toupper المعاكسة للدالة السابقة في عملها المحرف المُمرّر لها إلى مكافئه الكبير.

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

التوطين Localization

نستطيع التحكم بالإعدادات المحليّة للبرنامج من هنا، ويصرح ملف الترويسة <locale.h> دوال setlocale و localeconv وعددًا من الماكرو:

LC_ALL
LC_COLLATE
LC_CTYPE
LC_MONETARY
LC_NUMERIC
LC_TIME

تُستبدل جميع الماكرو بتعبير ثابت ذي قيمة عدد صحيح وتُستخدم القيمة الناتجة عن التعبير مكان الوسيط category في الدالة setlocale (يمكن تعريف أسماء أخرى أيضًا، ويجب أن يبدأ كل منها بـ LC_X، إذ يمثّل X المحرف الأبجدي الكبير)، ويُستخدم النوع struct lconv لتخزين المعلومات المتعلقة بتنسيق القيم الرقمية، ويُستخدَم CHAR_MAX للأعضاء من النوع char للدلالة على أن القيمة غير متوافرة في الإعدادات المحلية الحالية.

يحتوي lconv على عضو واحد على الأقل من الأعضاء التالية:

العضو الاستخدام تمثيله في إصدارات سي المحلية ملاحظات إضافية
char *decimal_point يُستخدم المحرف للفاصلة العشرية في القيم المنسقة غير المالية. "." ---
char *thousands_sep يُستخدم المحرف لفصل مجموعات من الخانات الواقعة على يسار الفاصلة العشرية في القيم المنسقة غير المالية. "" ---
char *grouping يعرّف عدد الخانات في كل مجموعة في القيم المنسقة غير المالية، وتحدد القيمة CHAR_MAX أنه لا يوجد أي تجميع إضافي مطلوب، بينما تحدد القيمة 0 أنه يجب تكرار العنصر السابق للخانات الرقمية المتبقية، وإذا استُخدمت أي قيمة أخرى فهي تمثل قيمة العدد الصحيح المُمثل لعدد الخانات التي تتألف منها المجموعة الحالية (المحرف اللاحق في السلسلة النصية يُفسَّر قبل التجميع). "" يحدد "‎\3" أن الخانات يجب أن تجمع كل ثلاثة في مجموعة ويشير محرف الإنهاء الفارغ terminating null في السلسلة النصية إلى تكرار ‎\3.
char *int_curr_symbol تُستخدم المحارف الأولى الثلاث لتخزين رمز العملة العالمي الأبجدي لإصدار سي المحلي، بينما يُستخدم المحرف الرابع للفصل بين رمز العملة العالمي والكمية النقدية. "" ---
char *currency_symbol يمثل رمز العملة للإصدار المحلي الحالي. "" ---
char *mon_decimal_point المحرف المُستخدم مثل فاصلة عشرية عند تنسيق القيم النقدية. "" ---
char *mon_thousands_sep يمثل فاصل مجموعات خانات الأرقام ذات القيم المنسقة بتنسيق نقدي. "" ---
char *mon_grouping يعرف عدد الخانات في كل مجموعة عند تنسيق قيم نقدية، وتُفسّر عناصره على أنها جزء من التجميع "" ---
char *positive_sign السلسلة النصية المُستخدمة للدلالة على قيمة نقدية غير سالبة. "" ---
char *negative_sign السلسلة النصية المُستخدمة للدلالة على قيمة نقدية سالبة. "" ---
char int_frac_digits عدد الخانات التي تُعرض بعد الفاصلة العشرية في قيمة نقدية منسقة عالميًا. CHAR_MAX ---
char frac_digits عدد الخانات التي تُعرض بعد الفاصلة العشرية في قيمة نقدية غير منسقة عالميًا. CHAR_MAX ---
char p_cs_precedes قيمة 1 تدل على وجوب إتباع currency_symbol بالقيمة عند تنسيق قيمة غير سالبة نقدية، بينما تدل القيمة 0 على إسباق currency_symbol بالقيمة. CHAR_MAX ---
char p_sep_by_space قيمة 1 تدل على تفريق رمز العملة من القيمة بمسافة فارغة عند تنسيق قيمة غير سالبة نقدية، بينما تدل قيمة 0 على عدم وجود أي مسافة فارغة. CHAR_MAX ---
char n_cs_precedes تشابه p_cs_precedes ولكن للقيم النقدية السالبة. CHAR_MAX ---
char n_sep_by_space تشابه p_sep_by_space ولكن للقيم النقدية السالبة. CHAR_MAX ---
char n_sign_posn يشابه p_sign_posn ولكن للقيم النقدية السالبة. CHAR_MAX ---
char p_sign_posn يمثل موقع positive_sign للقيم النقدية المنسقة غير السالبة. CHAR_MAX يتبع الشروط التالية: تُحيط الأقواس القيمة النقدية وcurrency_symbol. تسبق السلسلة النصية كل من القيمة النقدية و currency_symbol. تتبع السلسلة النصية القيمة النقدية و currency_symbol. تسبق السلسلة النصية القيمة currency_symbol. تتبع السلسلة النصية القيمة currency_symbol

دالة setlocale لضبط الإعدادات المحلية

يكون تعريف دالة setlocale على النحو التالي:

#include <locale.h>

char *setlocale(int category, const char *locale);

تسمح هذه الدالة بضبط إعدادات البرنامج المحلية، ويمكن ضبط جميع أجزاء الإصدار المحلي باختيار القيم المناسبة لوسيط التصنيف category كما يلي:

  • القيمة LC_ALL: تضبط كامل الإصدار المحلي.
  • القيمة LC_COLLATE: تعديل سلوك strcoll و strxfrm.
  • القيمة LC_CTYPE: تعديل سلوك دوال التعامل مع المحارف character-handling.
  • القيمة LC_MONETARY: تعديل تنسيق القيم النقدية المُعادة من دالة localeconv.
  • القيمة LC_NUMERIC: تعديل محرف الفاصلة العشرية لتنسيق الدخل والخرج وبرامج تحويل السلاسل النصية.
  • القيمة LC_TIME: تعديل سلوك strftime.

يمكن ضبط قيم الإعدادات المحلية إلى:

"C" تحديد البيئة ذات المتطلبات الدنيا لترجمة سي C
"" تحديد البيئة الأصيلة المعرفة حسب التطبيق
قيمة معرفة بحسب التنفيذ تحديد البيئة الموافقة لهذه القيمة

البيئة الافتراضية عند بداية البرنامج موافقة للبيئة التي نحصل عليها عند تنفيذ التعليمة التالية:

setlocale(LC_ALL, "C");

يمكن فحص السلسلة النصية الحالية المترافقة مع تصنيف ما بتمرير مؤشر فارغ null قيمةً للوسيط locale؛ نحصل على السلسلة النصية المترافقة مع التصنيف category المحدد للتوطين الجديد إذا كان من الممكن حصول التصنيف المحدد، وتُستخدم هذه السلسلة النصية في استدعاء لاحق للدالة setlocale مع تصنيفها المترافق لاستعادة الجزء الموافق من إعدادات البرنامج المحلية، وإذا كان التحديد غير ممكن الحصول نحصل على مؤشر فراغ دون تغيير الإعدادات المحلية.

دالة localeconv

يكون تصريح الدالة على النحو التالي:

#include <locale.h>

struct lconv *localeconv(void);

تُعيد هذه الدالة مؤشرًا يشير إلى هيكل من النوع struct lconv، ويُضبط هذا المؤشر طبقًا للإعدادات المحلية الحالية ويمكن تغييره باستدعاء لاحق للدالة localconv أو setlocale، ويجب ألّا يكون الهيكل قابلًا للتعديل بأي طريقة أخرى.

على سبيل المثال، إذا كانت إعدادات القيم النقدية المحلية الحالية مُمثّلةً حسب الإعدادات التالية:

IR£1,234.56 تنسيق القيم الموجبة
(IR£1,234.56) تنسيق القيم السالبة
IRP 1,234.56 التنسيق العالمي

يجب أن تحمل الأعضاء التي تمثّل القيم النقدية في lconv القيم التالية:

int_curr_symbol "IRP "
currency_symbol "IR£"
mon_decimal_point "."
mon_thousands_sep ","
mon_grouping "\3"
postive_sign ""
negative_sign ""
int_frac_digits 2
frac_digits 2
p_cs_precedes 1
p_sep_by_space 0
n_cs_precedes 1`
n_sep_by_space 0
p_sign_posn CHAR_MAX
n_sign_posn 0

ترجمة -وبتصرف- لقسم من الفصل Libraries من كتاب The C Book.

اقرأ أيضًا


تفاعل الأعضاء

أفضل التعليقات

لا توجد أية تعليقات بعد



انضم إلى النقاش

يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.

زائر
أضف تعليق

×   لقد أضفت محتوى بخط أو تنسيق مختلف.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   جرى استعادة المحتوى السابق..   امسح المحرر

×   You cannot paste images directly. Upload or insert images from URL.


×
×
  • أضف...