Zobrazit předchozí téma :: Zobrazit následující téma |
Autor |
Zpráva |
bolejt

Založen: 02. 05. 2009 Příspěvky: 45
|
Zaslal: 8. květen 2009, 00:05:49 Předmět: C++ a unicode |
|
|
chci pracovat s unicode s použitím C++ Standard Library a STL na více platformách (Windows, *nix), externí texty ukládám pouho pouze v utf-8. jak jsem předpokládal, není to tak jednoduché.
na linuxu jsem využil locale (přesněji "cs_CZ.utf8"), wide verze stringu a fstreamu, jenže tohle řešení padá na hubu hned v implementaci C++ Standard Library u MinGW, protože tam tak nějak wide verze streamů nejsou a také na Windows jsou locale zřejmě jiné plus wchar_t má odlišnou velikost. jistě, tohle by snad i vyřešil STLport (jako možné řešení jsem to nalezl v nějakém mailing listu), ale něco co by fungovalo bez nutnosti STLportu je asi lepší... pokud něco takového existuje :)
prakticky mě více méně nezajímá, jak bude vypadat string unvnitř (pokud si nebudu převádět uft-8 do čehosi více bajtového sám), jen bych potřeboval něco, co řekne, kolik je uvnitř znaků včetně správné indexace (ať už vracení znaku na pozici, tak find, substring atd.).
napadlo mě, že by řekněme můj "ustring" veřejně dědil od std::string (resp. std::basic_string<char>) a potřebné metody a operátory si upravil, ovšem tohle bude asi náročnější. ale myslím si, že méně náročné než vytvořit něco úplně vlastního.
mimochodem do konzole si klidně neASCII znaky mohou vypisovat jako ošklivý balast.
jo a extra knihovnu řešící unicode se mi přidávat do projektu nechce, pokud by to nebylo nutné.
takže, napadá někoho něco?
samozřejmě se nevydávám za C++ a všeho kolem toho pořádně znalého, takže celý tenhle příspěvek může být hromadou doměnek a pitomostí :) _________________ Ball ball8; |
|
Návrat nahoru |
|
 |
MD

Založen: 29. 07. 2007 Příspěvky: 437 Bydliště: Praha
|
Zaslal: 10. květen 2009, 16:46:33 Předmět: |
|
|
Ahoj, presne tenhle problem jsme ve firme resili. Bohuzel uz je to trosku dele a ja uz tam nepracuju, tak nahodim jen par takovych poznamek.
Pokud ti jde jen o to zjistit, kolik bytu znak v UTF8 ma, spocitat si kolik znaku je ve stringu, zjistit jestli ofset do stringu ukazuje na platny UTF8 znak, konverzi UTF8 <-> UTF(16)32, tak je to velmi jednoduche a tech par funkci si muzes dopsat sam. Tohle doporucuju, protoze nebudes mit problem pri prenaseni knihoven tretich stran z Linuxu na Winy a vlastne kamkoli jinam. Na to, jak to udelat se podivej sem: http://cs.wikipedia.org/wiki/UTF-8
Problem nastava, kdyz potrebujes delat poradne toUpper, ci prevadet na nejakou neunicodovou code page. Tam uz je to docela obtizne. Windowsy jsou na tom v tomhle ohledu lepe, takze doporucuju pouzivat funkce primo z winapi (WideCharToMultibyte).
Jak jsme to poresili na linuxech uz si ted nepamatuji. Zkouseli jsme nejake knihovny a mozna jsme nakonec rezignovali a na ignore case porovnavani jsme si udelali nejakou vlastni prevodni tabulku (asi z duvodu toho ze patricna knihovna byla moc velka nebo byl problem s jeji licenci nebo distribuci)
Jinak pro linux se nam hodne libilo UTF8 (radeji nez UTF32 a UTF16) a na windows je pohodlnejsi pracovat v UTF16.
Jinak std::string radeji neupravuj. Vetsina veci ti funguje s UTF8 i nadale, vcetne veci jako find, replace, ... jen nikdy nevyhledavas znak (pokud to teda neni ten s kodem pod 128, tam muzes v pohode), ale podstring. Chce si to uvedomit jak je to UTF8 delany. Viz wikipedie. _________________ - play with objects - www.krkal.org - |
|
Návrat nahoru |
|
 |
ladik-BigBoss

Založen: 28. 07. 2007 Příspěvky: 162
|
|
Návrat nahoru |
|
 |
bolejt

Založen: 02. 05. 2009 Příspěvky: 45
|
Zaslal: 15. květen 2009, 11:36:24 Předmět: |
|
|
konečně mám trochu volného času.
MD: já vím, s vlastním převodem UTF-8 do čehosi a zpátky počítám.
používat std::string mě napadlo, napsat si funkce int charAt(string& kde,index), size_t size(string& kde) a další.
nebo předpokládat, že wchar_t je minimálně dvoubajtový, využít std::wstring, přetížít globální operátory istream& operator>>(istream&,wstring&), ostream& operator<<(ostream&,wstring&) plus napsat vlastní getline(istream,wstring), vše převod z UTF-8 do UTF-16. vlastně UCS-2, tím myslím zaměřit se jen na Basic Multilingual Plane. ono dál za těma dvouma bajtama v UTF-16 už jsou jen vědecké a historické věci, ne?
nad problémem to upper a to lower jsem ani nepřemýšlel, holt to budu zatím úspěšně ignorovat.
mno ještě uvidím a snad rozumně vyřeším.
ladik-BigBoss: používal jsem Qt s jejich QString, teď jsem se vrátil k STL a k std::(w)string. případně jen zkopírování jejich ustring by nešlo díky licenci, protože mají LGPL, to bych potom musel nutně používat taky, jestli se nepletu. _________________ Ball ball8; |
|
Návrat nahoru |
|
 |
MD

Založen: 29. 07. 2007 Příspěvky: 437 Bydliště: Praha
|
Zaslal: 15. květen 2009, 12:12:54 Předmět: |
|
|
Spokojit se s Basic Plane je asi OK (i my jsme to tak udelali a asi jsme nebyli sami ) Tohle zjednoduseni ti dava, ze UTF16 ma vzdy 2 bajty na znak a UTF8 ma maximalne 3 bajty na znak. Samozrejme tam zavadis vedome bug, takze az ti tam nekdo napise text v mrtvem nebo umelem jazyce, tak se ti to sesype
Jeste zopakuju at je jasne ze si rozumime. Spousta operaci se stringy funguje stejne dobre nad UTF8 i nad ASCII (7 bitova sada). Stale muzes spolehat na to, ze text konci nulou, coz je jeden byte. Stale muzes v textu vyhledavat znaky s kodem pod 128 (mezera, '/', '*' atd.), stejne tak muzes vyhledavat libovolne UTF8 podstringy pomoci beznych funkci pro ASCII. Je jen velmi malo pripadu, kdy si potrebujes psat specialni funkce. To nastava treba tehdy, kdyz potrebujes po znacich posouvat kurzor, nebo oddelit od textu prvnich 5 znaku a pod. V UTF16, pokud se omezis na Basic Plane, samozrejme tyhle problemy nemas. Tam je spis opruz, ze jeden system ma wchar_t 16bitu a druhy 32  _________________ - play with objects - www.krkal.org - |
|
Návrat nahoru |
|
 |
Mnemonic

Založen: 28. 07. 2007 Příspěvky: 93
|
Zaslal: 15. květen 2009, 15:14:48 Předmět: |
|
|
MD napsal: |
UTF16, pokud se omezis na Basic Plane, samozrejme tyhle problemy nemas. Tam je spis opruz, ze jeden system ma wchar_t 16bitu a druhy 32  |
A je to takovej problem? Ve wme2 momentalne pouzivam v pameti vsude wstringy, a kdyz je potreba ukladat je nekde externe, prevedou se do utf8. Cekaji me nejaka nemila prekvapeni?  |
|
Návrat nahoru |
|
 |
MD

Založen: 29. 07. 2007 Příspěvky: 437 Bydliště: Praha
|
Zaslal: 15. květen 2009, 16:03:28 Předmět: |
|
|
Do Basic Plane se ti vejde cinstina, korejstina, arabstina, proste vsechno Ve wme zadny problem nevidim. Linuxovou verzi nemas, ne? (tam by byly problemy s portabilitou a s hledanim potrebnych knihoven)
Edit: Lidi si jen neuvedomuji ze 16bit wchar != unicode. Se 16bit wcharem by jsi mel pracovat jako s UTF16 a pocitat s tim, ze existuji i znaky mimo tu zakladni rovinu (ale to jsou jen davno mrtve nebo umele jazyky) a tyto znaky se v UTF16 koduji pomoci 4 bytu. No a s timhle skoro nikdo nepocita. _________________ - play with objects - www.krkal.org - |
|
Návrat nahoru |
|
 |
Mnemonic

Založen: 28. 07. 2007 Příspěvky: 93
|
Zaslal: 15. květen 2009, 16:54:17 Předmět: |
|
|
MD napsal: |
Linuxovou verzi nemas, ne? (tam by byly problemy s portabilitou a s hledanim potrebnych knihoven)
|
Tohle me prave zajima. Jsem myslel, ze STL je STL...
Jinak ze 16 bitu nepokryva komplet vsechny unicode znaky je mi znamo, ale obskurni jazyky neresim  |
|
Návrat nahoru |
|
 |
OndraSej

Založen: 28. 07. 2007 Příspěvky: 767 Bydliště: Brandýs nad Labem
|
Zaslal: 15. květen 2009, 17:27:48 Předmět: |
|
|
Mnemonic napsal: |
Tohle me prave zajima. Jsem myslel, ze STL je STL... |
STL sice je STL, ale třeba převody mezi znakovýma sadama neřeší. _________________ http://trionteam.net |
|
Návrat nahoru |
|
 |
Mnemonic

Založen: 28. 07. 2007 Příspěvky: 93
|
Zaslal: 15. květen 2009, 17:36:14 Předmět: |
|
|
Ale ja prave nechci prevadet znakove sady. Proto mam vsechny stringy jako wstring (utf16 nebo utf32 podle platformy) a pro prenosy je prevadim na utf8, kvuli rozdilne velikosti wchar_t (prevod z utf16/32 na utf8 a zpet si delam sam). |
|
Návrat nahoru |
|
 |
OndraSej

Založen: 28. 07. 2007 Příspěvky: 767 Bydliště: Brandýs nad Labem
|
Zaslal: 15. květen 2009, 18:29:21 Předmět: |
|
|
Mnemonic> Jasně. Já jsem to myslel tak, že zrovna STL na Linuxu není problém, ale že STL problémy kolem kódování a multi-byte řetězců neřeší. _________________ http://trionteam.net |
|
Návrat nahoru |
|
 |
bolejt

Založen: 02. 05. 2009 Příspěvky: 45
|
Zaslal: 15. květen 2009, 21:22:44 Předmět: |
|
|
MD napsal: |
Spokojit se s Basic Plane je asi OK (i my jsme to tak udelali a asi jsme nebyli sami :wink: ) Tohle zjednoduseni ti dava, ze UTF16 ma vzdy 2 bajty na znak a UTF8 ma maximalne 3 bajty na znak. Samozrejme tam zavadis vedome bug, takze az ti tam nekdo napise text v mrtvem nebo umelem jazyce, tak se ti to sesype :wink: |
no snad po těch zatracených hieroglyfech nikdo nešáhne! :)
MD napsal: |
Jeste zopakuju at je jasne ze si rozumime. Spousta operaci se stringy funguje stejne dobre nad UTF8 i nad ASCII (7 bitova sada). Stale muzes spolehat na to, ze text konci nulou, coz je jeden byte. Stale muzes v textu vyhledavat znaky s kodem pod 128 (mezera, '/', '*' atd.), stejne tak muzes vyhledavat libovolne UTF8 podstringy pomoci beznych funkci pro ASCII. Je jen velmi malo pripadu, kdy si potrebujes psat specialni funkce. To nastava treba tehdy, kdyz potrebujes po znacich posouvat kurzor, nebo oddelit od textu prvnich 5 znaku a pod. |
ano, vím, že ASCII (0-127) je vlastně podmnožinou UTF-8, ale kdybych právě narazil na tyhle případy, potom si musím udělat ten charAt(index) a asi i další. například kdybych chtěl vykreslovat znaky, definice znaků a jejich koordináty na textuře znaků bych měl v externím souboru, takže potom nutně musím jít po znaku ve stringu, který chci dostat na obrazovku. proto řešení s wstring mi připadá rozumnější.
MD napsal: |
V UTF16, pokud se omezis na Basic Plane, samozrejme tyhle problemy nemas. Tam je spis opruz, ze jeden system ma wchar_t 16bitu a druhy 32 :? |
ten rozdíl tam sice bude, ale když to bude fungovat... _________________ Ball ball8; |
|
Návrat nahoru |
|
 |
|