سؤال

لدينا مجموعة من التطبيقات التي تم تطويرها لمجموعة أحرف ASCII.الآن، نحاول تثبيته في أيسلندا، ونواجه مشكلات حيث تتعطل الأحرف الأيسلندية.

نحن نعمل على حل مشكلاتنا، لكنني كنت أتساءل:هل يوجد "دليل" جيد لكتابة تعليمات برمجية C++ مصممة لأحرف 8 بت والتي ستعمل بشكل صحيح عند إعطاء بيانات UTF-8 لها؟

لا أتوقع أن يقرأ الجميع معيار Unicode بالكامل، ولكن إذا كان هناك شيء متاح أكثر سهولة في الفهم، فأنا أرغب في مشاركته مع الفريق حتى لا نواجه هذه المشكلات مرة أخرى.

إعادة كتابة كافة التطبيقات لاستخدام wchar_t أو بعض تمثيلات السلسلة الأخرى غير ممكنة في الوقت الحالي.سألاحظ أيضًا أن هذه التطبيقات تتواصل عبر الشبكات مع الخوادم والأجهزة التي تستخدم أحرف 8 بت، لذلك حتى لو قمنا باستخدام Unicode داخليًا، سنظل نواجه مشكلات في الترجمة عند الحدود.في أغلب الأحيان، تقوم هذه التطبيقات فقط بتمرير البيانات؛إنهم لا "يعالجون" النص بأي طريقة سوى نسخه من مكان إلى آخر.

أنظمة التشغيل المستخدمة هي Windows و Linux.نحن نستخدم std::string وسلاسل C القديمة.(ولا تطلب مني الدفاع عن أي من قرارات التصميم.أنا فقط أحاول المساعدة في إصلاح الفوضى.)


وفيما يلي قائمة بما تم اقتراحه:

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

المحلول

يبدو هذا كدليل سريع شامل:
http://www.cl.cam.ac.uk/~mgk25/unicode.html

نصائح أخرى

فقط كن نظيفًا بنسبة 8 بت، في أغلب الأحيان.ومع ذلك، يجب أن تكون على دراية بأن أي حرف غير ASCII ينقسم عبر وحدات بايت متعددة، لذلك يجب أن تأخذ هذا في الاعتبار في حالة فصل الأسطر أو اقتطاع النص للعرض.

يتمتع UTF-8 بميزة أنه يمكنك دائمًا معرفة مكانك بحرف متعدد البايت:إذا تم تعيين البت 7 وإعادة تعيين البت 6 (البايت هو 0x80-0xBF) فهذا هو بايت لاحق، بينما إذا تم تعيين البتات 7 و6 وإعادة تعيين 5 (0xC0-0xDF) فهو بايت أولي مع بايت زائد واحد؛إذا تم تعيين 7 و6 و5 وتم إعادة تعيين 4 (0xE0-0xEF)، فهي بايتة أولية تحتوي على وحدتي بايت زائدتين، وهكذا.عدد البتات المتتالية المعينة عند البت الأكثر أهمية هو إجمالي عدد البايتات التي يتكون منها الحرف.إنه:

110x xxxx = حرف ثنائي البايت
1110 xxxx = حرف ثلاثي البايت
1111 0xxx = حرف ذو أربعة بايت
إلخ

الأبجدية الأيسلندية كلها موجودة في ISO 8859-1 ومن ثم Windows-1252.إذا كان هذا تطبيقًا في وضع وحدة التحكم، فكن على دراية بأن وحدة التحكم تستخدم صفحات الرموز الخاصة بـ IBM، لذلك (اعتمادًا على لغة النظام المحلية) قد يتم عرضها بتنسيق 437 أو 850 أو 861.لا يوجد لدى Windows دعم العرض الأصلي لـ UTF-8؛يجب عليك التحويل إلى UTF-16 واستخدام Unicode APIs.

إن استدعاء SetConsoleCP وSetConsoleOutputCP، وتحديد مخطط الشفرة 1252، سيساعد في حل مشكلتك، إذا كان تطبيقًا في وضع وحدة التحكم.لسوء الحظ، يجب أن يكون خط وحدة التحكم المحدد هو الخط الذي يدعم صفحة الرموز، ولا أستطيع رؤية طريقة لتعيين الخط.تعتمد الخطوط النقطية القياسية صفحة الترميز اللغوي OEM الافتراضية للنظام فقط.

انتبه إلى أن الكود الموحد الكامل لا يتناسب مع الأحرف ذات 16 بت؛لذا استخدم إما أحرفًا 32 بت، أو ترميزًا متغير العرض (UTF-8 هو الأكثر شيوعًا).

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

قد ترغب في التحقق من ذلك وحدة العناية المركزة.قد يكون لديهم وظائف متاحة من شأنها أن تجعل العمل مع سلاسل UTF-8 أسهل.

تستخدم اللغة الأيسلندية ISO Latin 1، لذا فإن ثمانية بتات ستكون كافية.نحن بحاجة إلى مزيد من التفاصيل لمعرفة ما يحدث.

يمكن دعم اللغة الأيسلندية، مثل الفرنسية والألمانية ومعظم اللغات الأخرى في أوروبا الغربية، باستخدام مجموعة أحرف 8 بت (CP1252 على نظام التشغيل Windows، وISO 8859-1 المعروف أيضًا باسم Latin1 على *x).كان هذا هو النهج القياسي قبل اختراع Unicode، ولا يزال شائعًا جدًا.كما قلت، لديك قيد يتمثل في أنه لا يمكنك إعادة كتابة تطبيقك لاستخدام wchar، ولست بحاجة إلى ذلك.

لا ينبغي أن تتفاجأ من أن UTF-8 يسبب مشاكل؛يقوم UTF-8 بتشفير الأحرف غير ASCII (على سبيل المثال.الأحرف اللاتينية المحركة، thorn، eth، إلخ) بحجم 2 بايت لكل منهما.

النصيحة العامة الوحيدة التي يمكن تقديمها بسيطة جدًا (من الناحية النظرية):(1) حدد ما هي الشخصية التي ستقوم بدعمها (Unicode ، Latin1 ، CP1252 ، ...) في نظامك (2) إذا تم تزويدك بالبيانات المشفرة بطريقة أخرى (على سبيل المثالUTF-8) ثم قم بتحويله إلى المعيار الخاص بك (على سبيل المثال.CP1252) على حدود النظام (3) إذا كنت بحاجة إلى توفير البيانات المشفرة بطريقة أخرى ، ...

قد ترغب في استخدام أحرف عريضة (wchar_t بدلاً من char وstd::wstring بدلاً من std::string).هذا لا يحل مشاكلك تلقائيًا بنسبة 100%، ولكنه خطوة أولى جيدة.

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

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