C++-ban mire használjuk a wide character (wchar_t) típust?
Ugyan a wchar_t mérete nincs a szabványban definiálva így elvileg lehet akár ugyan az is mint a char, Linuxon 32 bites, Windowson 16. Ezt figyelembe kell venni a használatakor. Több okból is a wchar_t szoktuk mégis használni a fix hosszúságú char típusok helyett: egyik az hogy a fordító a locale alapján képes a char -> wchar_t konverzióra, a másik hogy a wchar_t típusú karakterláncokhoz elérhetőek a függvények a standard könyvtárból, míg a fix hosszúságú típusokhoz magadnak kell megírni őket.
wchar_t típust támogató függvények pl:
wprintf, wscanf, wcslen, wcscpy, wcscmp, wmemcpy, wcstoi, stb..
Minden ami a sima char típushoz is van:
"És egy wchar_t változó csak egy darab pl. utf-8 kódolású karaktert tud tárolni, ugye, nem többet?"
Egy wchar_t egy karaktert tárol. Az hogy ezt milyen módon teszi meg implementáció és locale függő.
Hát én éppen ezzel foglalkozok jelen pillanatban, hogy C++ban natívan (relatív platformfüggetlenül) kezeljük az UTF-8 karakterkódolást.
Csak, hogy:
- wchar_t: NEM alkalmas, mert ahogy fentebb is írták fordító/platform függően más és más lehet a mérete, ami ugyebár emiatt instabillá teszi a programot.
- char32_t: Mivel az UTF-8 legfeljebb 4 byte-on tárol és nem konstans 4 byte-on, így ez se a legmegfelelőbb. :(
- char16_t, char: Ebbe meg alapjáraton nem fér bele egy karakter se, ami több mint 1 vagy 2 byte.
- Boost library: Nem tartalmaz olyan elemet, amivel dinamikusan tudjuk kezelni az UTF-8at. Vagyis én nem találtam benne ilyet. Csak konverziókat erről arra.
Mivel az UTF-8 úgy működik, hogy az alap ASCII karaktereket 1byte-on tárolja, és saját jelzésrendszert használ a byte-ok számának jelzésére. Sajnos nincs se meta adat, se fejléc.
1byte: 0xxxxxxx
2byte: 110xxxxx 10xxxxxx
3byte: 1110xxxx 10xxxxxx 10xxxxxx
4byte: 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
Tehát ebből kiindulva az első byte-ot bitenkénti "&"-ve egy megfelelő maszkal kiszámolhatod, hogy a karakter mekkora byte-on tárolódik. Innentől használható az egyszerű "string".
Természetesen figyelni kell arra, hogy a string 3. karaktere !NEM a UTF-8 3. karaktere lesz, hanem pl. egy 3 byte-os karakternek az utolsó byte-ja.
Pl. egy 3 byte-os karakter meghatározása esetén:
char b = str[0] //vagy str.at(0)
if((b & 0xF0) == 0xE0) { /* ez 3byte-os */ } else { /* Nem 3 byte-os */ }
példa:
1) Megszámolhatjátok a karaktereket és a byte-okat, ami ez esetben egyezik.
string a = "Ez egy UTF-8";
string b = "\x45\x7A\x20\x65\x67\x79\x20\x55\x54\x46\x2D\x38\x2E";
// true <<-- a == b
2) Amennyiben támogatott az UTF-8 bevitel a fejlesztőkörnyezetben pl. NetBeans-ben, úgy ez is működik.
string c = "öüóőúéáűí";
string d = "\xC3\xB6\xC3\xBC\xC3\xB3\xC5\x91\xC3\xBA\xC3\xA9\xC3\xA1\xC5\xB1\xC3\xAD";
// true <<-- c == d
A megjelenítés és az UTF-8 értelmezése sajnos már GUI függő. Linux terminál megjeleníti, UTF-8as környezetek megjelenítik, de ASCII avagy Latin-X alapú terminálok már NEM.
Kapcsolódó kérdések:
Minden jog fenntartva © 2024, www.gyakorikerdesek.hu
GYIK | Szabályzat | Jogi nyilatkozat | Adatvédelem | Cookie beállítások | WebMinute Kft. | Facebook | Kapcsolat: info(kukac)gyakorikerdesek.hu
Ha kifogással szeretne élni valamely tartalommal kapcsolatban, kérjük jelezze e-mailes elérhetőségünkön!