UTF-8: Boshidan-oxirigacha! 2-qism! utf8_strlen!
Agar UTF-8 haqida qisqacha ma’lumot olmoqchi bo’lsangiz, 1-qismga o’ting.
Agar 1-maqolani o’qigan bo’lsangiz, UTF-8 da belgilar 1 baytdan 4 baytgacha bo’lishi mumkin deb o’tganman. Agar shunday bo’lsa, «AЩぁ𐄳» qator (string) uzunligi nechchi bo’lishi kerak?
#include#include #include int main() { std::string str{"AЩぁ𐄳"}; std::cout Dastur natijasi:
LENGTH = 10Bizga esa 4 kerak.
Keling oldin UNICODE dagi belgi UTF-8 ga qanday tartibda o'tkazilishini o'rgnaib chiqsak. U 3 da qadamdan iborat.
1-qadam: UNICODE dagi belgilarni saqlashga kerak bo'ladigan BAYT lar sonini aniqlash, quyidagi jadval asosida bo'ladi.
BELGILAR ORALIG'I (UNICODE) KERAK BO'LADIGAN BAYTLAR SONI 00000000-0000007F 1 00000080-000007FF 2 00000800-0000FFFF 3 00010000-0010FFFF 4 Ya'ni, agar biz UNICODE dagi U+0080 belgini UTF-8 da saqlamoqchi bo'lsak, bizga 2 bayt kerak bo'ladi.
2-qadam: Kerak bo'lgan baytlar sonidan kelib chiqib, quyidagi jadval asosida eng birinchi turgan baytning bit qiymatlarini o'zgartirish kerak.
0xxxxxxx agar 1 bayt bo'lsa 110xxxxx agar 2 bayt bo'lsa 1110xxxx agar 3 bayt bo'lsa 11110xxx agar 4 bayt bo'lsa 1 tadan ko'p bo'lgan holatda, keyingi baytlarning boshida har doim 10 (ikkilikda) bo'lishi lozim. Umuman olganda, baytlar sonidan kelib chiqib quyidagi jadvalni shablon sifatida olsak bo'ladi.
Baytlar soni Kerakli bitlar Shablon 1 7 0xxxxxxx 2 11 110xxxxx 10xxxxxx 3 16 1110xxxx 10xxxxxx 10xxxxxx 4 21 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx xxxx - bular UNICODE dagi qiymatni saqlashga ishlatiladigan joylar (bit ko'rinishida).
3-qadam: UNICODE dagi birorta belgini olib, uning qiymatidan kelib chiqib keraklicha bayt uzunlikni tanlash kerak va xxxx larning o'rniga UNICODE dagi belgi qiymatini joylashtirish kerak. Ortib qolgan joylar esa 0 bilan to'ldiriladi.
Yuqoridagi 3-da qadam bu tarjima (wikipediadan). Endi keling, misol tariqasida ketma-ket tushuntirsam. Sal murakkab bo'lsada, bir vaqtning o'zida 4 ta belgi bilan ishlasak, manimcha tushinish oson bo'ladi.
Belgilar (UNICODE da):
IZOHBELGI A Щ ぁ 𐄳 UNICODE dagi kodi U+0041 U+0429 U+3041 U+10133 Kerak bo'ladigan baytlar soni 1
[00000000-0000007F] oraliqda2
[00000080-000007FF] oraliqda3
[00000800-0000FFFF] oraliqda4
[00010000-0010FFFF] oraliqdaIkkilik sanoq sistemada ko'rinishi 1000001 10000101001 11000001000001 10000000100110011 2-qadamdagi shablonlardan foydalanib "x" larga mos uzunlikka ajratsak, yuqoridagi ikkilikdagi qiymatlarini:
0xxxxxxx 1000001 110xxxxx 10xxxxxx 10000 101001 1110xxxx 10xxxxxx 10xxxxxx 11 000001 00000 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 10000 000100 110011
IZOHBELGI A Щ ぁ 𐄳 Yuqoridagini mox ravizda x lar o'rniga qiymatlarni joylashtiramiz, yetmay qolganiga 0 qo'yamiz 01000001 11010000 10101001 11100011 10000001 10000001 11110000 10010000 10000100 10110011 Endi shu 2 likdagi qiymatlarni 16 likda yozamiz. 0x41 0xD0A9 0xE38181 0xF09084B3 UTF-8 dagi natijalar esa quyidagicha:
A - U+0041 = 0x41
Щ - U+0429 = 0xD0A9
ぁ - U+3041 = 0xE38181
𐄳 - U+10133 = 0xF09084B3Demak xulosa: Agar baytning boshidagi bitlari mos ravishda:
0 bo'lsa, demak u 1 baytli UTF-8 belgi.
110 bo'lsa, demak 2 baytli belgi
1110 bo'lsa demak, 3 baytli belgi
11110 bo'lsa, demak 4 baytli belgi.
Shu qoidadan kelib chiqib, utf8_strlen funksiyamiz quyidagi ko'rinishda bo'ladi.
#include#include #include int utf8_strlen(const std::string& s) { int len = 0; int i = 0; while(i Natija:
LENGTH = 10 UTF8 LENGTH = 4 UTF8 LENGTH2 = 4Eslatma: utf8_strlen funksiya utf8_strlen2 ga nisbatan tez ishlaydi, chunki utf8_strlen da birinchi bayt tekshirilib qolganlari shundoq tashlab ketiladi. Ikkinchi funksiyada esa, bayt boshi 10 dan (ikkilikda) boshlaganlarni tekshiriladi. Shuning uchun ikkinchi funksiya 0 dan s.length() gacha to'liq aylanadi.
Manimcha bugunga yetarli.
Umumiy Dasturlash
UTF-8: Boshidan-oxirigacha! 2-qism! utf8_strlen!