Autorovi velké plus a vznášedlo plné úhořů za vhodně vybrané texty. :-)
Názory k článku
Napsat správně mezinárodní aplikaci v Qt nemusí být snadné
Re: Příklady ve článku
celé vláknoMaj hovrkraft is ful of íls. :-)
Programovani ve windows je nestandardni
celé vláknoTo jste me pobavil, jeste jeden ajtacky smradlavy blabol prosim!
Re: Programovani ve windows je nestandardni
celé vláknoA podle jakeho standardu ty funkce pro praci s terminalem ve Windows jsou?
... presne tak, zadneho. Panove z MS si je vycucali z prstu.
Kazdopadne konzolovy vystup z Qt je lepsi delat pres Qt, nez se spolehat na funkce OS, ktere jsou z pohledu Qt nestandardni vsechny. Konkretne k tomu slouzi trida QTextStream, ktere se da predat stdout/stderr/popisovac souboru/etc. Kodovani se nastavuje pres setCodec().
S Windows command line muzou byt problemy taky, protoze ve vychozim stavu neumi zobrazit unicode, ale jenom lokalni codepage (u nas napr. 1250). Je potreba si v ni nastavit font, ktery unicode zvladne (ne-obrazkovy).
Viz: http://stackoverflow.com/questions/1259084/what-encoding-code-page-is-cmd-exe-using
Dalsi problem je, ze kompilator musi umet precist a spravne ulozit retezce ze zdrojaku. Pokud jich pouzivate vice (treba MSVC a GCC), muzou vzniknout problemy s kodovanim. MS kompilator predpoklada, ze delate v pribalenem IDE a vse je bud v UTF16 nebo v lokalni mutaci MS kodovani. U prenositelne aplikace tedy jakekoliv retezce s narodnimi znaky rozhodne nepatri do zdrojaku. Ty je lespi umistit do nejakeho jineho souboru, kde presne vite co se deje s jeho obsahem. Ve zdrojaku nechte ciste ASCII. Dost to zjednodussi lokalizaci programu a nestane se Vam, ze nekdo posle patch s rozbitymi retezci/kodovanim, na kterych si nasledne nektery kompilator vylame zuby :)
Drobny Qt uvod: http://www.youtube.com/wat ch?v=lz9deRYwNFY
PS: proc me to nechce vzit slovo ,,wat ch'' vcelku?
Re: Programovani ve windows je nestandardni
celé vláknoDíky za velmi objektivní příspěvek. Ten unicode ve Windows konzoli je challenge a zdá se to průstřelné až od Win7 (diskuze dole - změna fontu programátorsky). Nicméně díky za připomínku, že se radši nespoléhat, že kompilátor správně rozpozná a zpracuje unicode znaky v našem zdrojáku. Jediná diakritika v anglicky mluvící aplikaci je často pouze jméno českého programátora v About boxu. Na toto bude zřejmě dostatečné nahradit diakritické znaky ve zdrojáku "hexa-reprezentací". Pro opravdovou lokalizaci se pak asi nejlépe vrhnout na standardní přístup Qt (QObject::tr()).
Chybička u popisu UTF-8
celé vláknoJeden znak může při použití UTF-8 zabrat maximálně čtyři bajty, ne šest.
Re: Chybička u popisu UTF-8
celé vláknoBits Last code point Byte 1 Byte 2 Byte 3 Byte 4 Byte 5 Byte 6 7 U+007F 0xxxxxxx 11 U+07FF 110xxxxx 10xxxxxx 16 U+FFFF 1110xxxx 10xxxxxx 10xxxxxx 21 U+1FFFFF 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx 26 U+3FFFFFF 111110xx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 31 U+7FFFFFFF 1111110x 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx 10xxxxxx
viz Wiki
Re: Chybička u popisu UTF-8
celé vlákno0000 0000-0000 007F | 0xxxxxxx
0000 0080-0000 07FF | 110xxxxx 10xxxxxx
0000 0800-0000 FFFF | 1110xxxx 10xxxxxx 10xxxxxx
0001 0000-0010 FFFF | 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
viz RFC 3629 ;-)
Re: Chybička u popisu UTF-8
celé vláknoJo, na windowsácké UTF-16 to dá, ale jak do toho nacpeš UTF-32? A neříkej že to se ti NIKDY stát nemůže, čtyřbytové IP adresy také měly stačit navždy...
Re: Chybička u popisu UTF-8
celé vláknoJak? Jednoduše! Musíš si uvědomit, čím UTF-? jsou a čím nejsou! Je to způsob, jak kódovat číselné kódy unicode znaků do bajtů. No a unicode prostor má rozsah 000000-10FFFF. Z toho ti plynou dvě věci:
- V případě použití UTF-8 budeš potřebovat maximálně 4 bajty. Nejde totiž o to pomocí UTF-8 ukládat 32 bitová čísla, ale unicode kódy znaků!
- V případě použití UTF-32 ne každá 32 bitová hodnota je přípustná (kóduje nějaký unicode znak).
Re: Chybička u popisu UTF-8
celé vláknoJasně, a také 640 KB musí stačit každému a se Sovětským svazem na věčné časy ;-) Kromě toho žádná další RFC už také nikdy nebudou a nezmění to zase jinak... Mimochodem, ne 32 ale 31 bitová, jak píše CHe níže.
Re: Chybička u popisu UTF-8
celé vláknoTakže ty tedy říkáš, že mé tvrzení, že znak kódovaný v UTF-8 podle normy nemůže zabrat více jak čtyři bajty, je nepravdivé, protože v budoucnu se může objevit nová norma? Ty jsi teda kus demagoga.
Re: Chybička u popisu UTF-8
celé vláknoNebylo by to poprvé, co by Unicode Consortium něco takového udělalo.
Re: Chybička u popisu UTF-8
celé vláknoAž se změní, tak se změní. Ale nemá smysl nyní tvrdit a argumentovat, že těch bajtů může být maximálně šest, když žádný takový znak v unicodu neexistuje a podle aktuální normy existovat nemůže. A až se norma změní, bude to třeba více než šest ;-)
Re: Chybička u popisu UTF-8
celé vláknoAle může, protože natruc budu (a nejen já) používat program z roku 2001, který na nějakou aktuální normu dlabe :-P
Re: Chybička u popisu UTF-8
celé vláknoTak mi napiš alespoň jeden znak, který podle stavu z roku 2001 potřebuje v UTF-8 šest bajtů ;-)
Re: Chybička u popisu UTF-8
celé vláknoMimochodem, ne 31 ale 32 bitová, jak jsem již psal. Neboť i když byl unicode prostor původně 31 bitový, nic to nemění na tom, že:
UTF-32 is the simplest Unicode encoding form. Each Unicode code point is represented directly by a single 32-bit code unit. (Unicode Standard 6.0)
Přesto ale:
As for all of the Unicode encoding forms, UTF-32 is restricted to representation of code points in the range 0-10FFFF - that is, the Unicode codespace. This guarantees interoperability with the UTF-16 and UTF-8 encoding forms. (Unicode Standard 6.0)
Re: Chybička u popisu UTF-8
celé vláknoThe original specification allowed for sequences of up to six bytes, covering numbers up to 31 bits (the original limit of the Universal Character Set). In November 2003 UTF-8 was restricted by RFC 3629 to four bytes covering only the range U+0000 to U+10FFFF, in order to match the constraints of the UTF-16 character encoding.
viz Wiki... :)
RFC 2044 (1996): 4 octets
RFC 2279 (1998): 6 octets
RFC 3629 (2003): 4 octets
článek k ničemu
celé vláknospíš mně to přijde jako PR na Qt, než solidní článek.
Re: článek k ničemu
celé vláknoAno, QT potřebuje PR jak prase drbání... :-)))
Re: článek k ničemu
celé vláknoAno. Kdyby šlo o lokalizované aplikace obecně, tak fajn, ale v Qt je to neexistující problém.
Co je na tom komplikovaného?
celé vlákno#include <stdio.h>
#include <windows.h>
int main(void)
{
SetConsoleOutputCP(65001);
printf("%s\n", "PĹ™Ăliš ĹľluĹĄouÄŤkĂ˝ kĹŻĹ"); /* UTF-8 */
printf("%S\n", L"Text"); /* UTF-16 */
return(0);
}
Pozn.: když se nastaví např. Lucida Console, tak to funguje skvěle ;)
Pozn.: ekvivalentem funkčního volání SetConsoleOutputCP(65001) je příkaz "chcp 65001"
Re: Co je na tom komplikovaného?
celé vláknoA nevěděl byste náhodou, jak nastavit Lucida Console programátorsky? Vámi uvedený kód je známý (alespoň mě), ale změnit ten font...
Re: Co je na tom komplikovaného?
celé vláknoRe: Co je na tom komplikovaného?
celé vláknoZkoušel jsem. Nefunguje. Navíc se nedá specifikovat font, který chci. Alespoň indexu do tabulky, kde jsou pouze rozměry fontu, neříkám výběr. To je spíše změna velikosti fontu udělaná přes obludné API. (Microsoft zde propadá, ač je to nedokumentovaná funkce.)
Nicméně díky za link.
Re: Co je na tom komplikovaného?
celé vláknoRe: Co je na tom komplikovaného?
celé vláknoWindows je asi hrozná platforma... :-)
Něco takového určitě do své aplikace nechci :-) .
Re: Co je na tom komplikovaného?
celé vláknoVe Vistách a 7mičkách lze použít:
#include <windows.h>
#include <strsafe.h>
int main(void)
{
CONSOLE_FONT_INFOEX cfie;
ZeroMemory(&cfie, sizeof(cfie));
cfie.cbSize = sizeof(cfie);
cfie.dwFontSize.Y = -20;
cfie.FontFamily = FF_DONTCARE;
cfie.FontWeight = 400;
StringCbCopyW(cfie.FaceName, sizeof(cfie.FaceName), L"Lucida Console");
SetCurrentConsoleFontEx(GetStdHandle(STD_OUTPUT_HANDLE), FALSE, &cfie);
return(0);
}
ve starších verzích buď to harakiri, co tu někdo posílal jako odkaz, nebo ho nastavit jako výchozí font na daném zástupci a spoléhat, že ho nikdo nezmění.
P.S.: zkoušel jsem podporu UTF-16 v printf() a máte pravdu, konzole Windows fakt stojí za ........ zlámanou grešli, spolehlivě funguje skutečně pouze WriteConsoleW() :/
Re: Co je na tom komplikovaného?
celé vláknoNaprosto souhlasím. Windowsová konzole je peklo. Pokud opominu Win7 a SetCurrentConsoleFontEx, tak mám pocit, že není cesta, jak spolehlivě vypsat unicode text do konzole. Nesouhlasí-li někdo, ať pošle vyzkoušený příklad. Osobně mu za něj poděkuji.
chyby
celé vláknoKód
QString s(a+b+c+d+e+f+g);
std::cout << s;
je obecně špatně. Qt lze nakonfigurovat bez podpory STL, je tedy potřena zkontrolovat příslušný define, než si toto můžete v kódu dovolit (nebo si ručně přetížit daný operátor).
Předpoklad použití UTF-8 pro názvy souborů na linuxu je opět špatný. Proto např. v glib existují funkce typu g_filename_to/from_utf8. Qt se o to naštěstí postará samo, pokud použijete jeho funkce. Ale tvrdit, že funkci fopen předáte utf-8 je blbost.
UTF-16 se ve Windows používá až od Windows XP. Před tím to bylo UCS-2. Ale dobře, nemá smysl podporovat již delší dobu nepodporované verze, píšu to jen pro upřesnění.
Při použití wchar_t není standardem zaručeno použití UTF-16 či UTF-32 a je to jen vaše doměnka. Záleží na kompilátoru, jak váš řetězec vytvoří. K tomuhle budou v C++0x prefixy u a U a nové typy char16_t a char32_t.
Paměťové nároky
celé vláknoČlánek, zdá se, trochu zmatkuje i v případě paměťových nároků. Pro jednotlivé rozsahy a kódování by náročnost měla být tato:
unicode rozsah | UTF-8 | UTF-16 | UTF-32 -------------------------------------------------- 0000 0000 - 0000 007F | 1B | 2B | 4B 0000 0080 - 0000 07FF | 2B | 2B | 4B 0000 0800 - 0000 FFFF | 3B | 2B | 4B 0001 0000 - 0010 FFFF | 4B | 4B | 4B
UTF-8 je tedy horší než UTF-16 na rozsahu 0800-FFFF, a to pouze o jeden bajt.
Co se týče v článku zmíněné cyrilice, ta používá rozsah 0400-04FF. Její znaky tedy zaberou jak v UTF-8 tak v UTF-16 shodně dva bajty. Dokonce i na tu arabštinu (rozsah 0600-06FF) u obou vystačí ještě dva bajty.
Ta japonská věta je špatně
celé vláknoVím, je to sice jen na ukázku, ale ta chybějící koncovka u slovesa v té japonské větě bije do očí.
Re: Ta japonská věta je špatně
celé vláknoTaky jsem si toho všiml, ale přišlo mi až nepatřičné na to upozorňovat. Ještě že nejsem "first".
Re: Ta japonská věta je špatně
celé vláknoTak, a už vím, že programátoři se s oblibou učí japonsky. :-)
L"' wstring
celé vláknoNepíšete, jakou chybu vám ta ruština vypisuje, ale tipuji to na špatně nastavenou vstupní kódovou stránku (-finput-charset=utf8)
Re: Napsat správně mezinárodní aplikaci v Qt nemusí být snadné
celé vlákno"České a německé znaky se sice zobrazily správně, ale japonština či ruština ne"
Jen taková malá technická - když už tu jiní upozornili na chybu v japonštině, dovoluji si upozornit, že ukázkový text není rusky, ale bulharsky. ;-)
Re: Napsat správně mezinárodní aplikaci v Qt nemusí být snadné
celé vláknoDěkuji všem za připomínky k cizím textům. Nepochybně jste jejich analýze věnovali mnohem více času než já při copy-and-paste z webové stránky ;-) . Obdiv vašim jazykovým znalostem :-) .
Nesmyslný článek
celé vláknoKdyby se vyškrtaly všechny řádky, které se netýkají Qt, zůstane - počítal jsem to! - osm řádků, které samy o sobě nedávají smysl. Plyne mi z toho, že celý článek nedává smysl.
Psát multiplatformní vícejazyčné aplikace čistě v Qt je velmi snadné, stačí využívat pro práci s textem prostředky Qt. Odpusťte si platformě závislé věci (WriteConsoleW) nebo věci s UTF nefungující (std) a uvidíte, že kód pro Linux i pro Windows může vypadat úplně stejně.
Napsal jsem stovky tisíc řádků v Qt aplikacích jak pro Linux tak pro Windows a zvěrstva jako je podmíněný překlad jsem nikdy neměl potřebu použít. Kód je stoprocentně shodný pro obě platformy.
Re: Nesmyslný článek
celé vláknoNelze nez souhlasit uz veta:
"Pro zjištění skutečného počtu znaků můžeme použít například funkci mbstowcs()."
Tato funkce ma hlavni funkci na prevod char->wchar_t a vydavato za funkci na zjisteni delky misto funkce primo pro toto urcene wcslen().
V clanek narazi na zajimave tema, nu obsahove je na dve veci. Jak napsal P.Bravenec tak nelze nez souhlasit. Kod co je v ukazkach je slabe receno divne.
Re: Nesmyslný článek
celé vláknoK panu Bravencovi: Dal jste si článek do souvislosti s Qt, což bohužel zapřičinila redakce, která změnila můj název článku zřejmě během jazykové korektury aniž by mě o tom informovala a aniž bych měl možnost to ovlivnit. Původně to mělo být o unicode a jeho použití napříč platformami. Již včera jsem informoval redakci, že měnit větu v článku je ok, ale název? A bez vědomí autora?
A teď druhá věc: Jestli jste nepoužíval podmíněný překlad, tak pochybuju, že jste opravdu programátor, nebo možná děláte jen GUI. Qt je užasné a používáme jej ve firmě (jeden kód pro všechny platformy), avšak jsou věci, které v Qt nenapíšete. Například nespustíte child process třídou QProcess s elevací práv procesu na Windows. Qt to neumí, Linux neví co to je a je nutno použít funkce ShellExecuteEx a podmíněného překladu.
Pan Karel2: Děkuji za přípomínku ohledně wcslen a mbstowcs, avšak mbstowcs lze opravdu použít ekvivalentním způsobem jak wcslen. Nicméně máte pravdu, že wcslen se hodí lépe. Jestli se Vám článek nelíbí, jak píšete, napište svůj. Je na světě hodně kecalů, ale málo mužů činu. Já jsem s článkem spokojen, neboť mi v diskuzi poskytl mnoho nových impulzů v některých problematických otázkách a platformách (Windows).
Re: Nesmyslný článek
celé vláknoMáte pravdu. Primárně dělám vše v Linuxu. V linuxu aplikace i překládám (mingw) a taky mi zde běží všechny serverové části (často v Qt, pouze konzolové aplikace). Pro Windows mi naštěstí stačí psát jen GUI aplikace, kde jsem opravdu neměl nikdy potřebu sáhnout po podmíněném překladu. Pro zadávání řetězců mi pak stačí používat trUtf8(), případně tr() spolu s nástroji pro překlad. Pokud potřebuji zadat nějaké platformě závislé věci (cesty k souborům a podobně), řešívám to přes konfigurační dialogy.
Jinak mně kdysi tady na rootu název článku nezměnili... a připadám si jako trouba ještě dnes :-)
Re: Nesmyslný článek
celé vláknoTo je prča - slova l*****se, lupdate či linguist vyhodnocuje root jako spam a nedovolí takový příspěvěk zadat.
Cyrilice
celé vláknoU cyrilice bude většina znaků zabírat 2 byte, ať použijete UTF-8 nebo UTF-16. Pokud budete kombinovat cyrilici a ascii znaky (číslice, čárky, tečky, závorky, …), pak bude malinko úspornější UTF-8.
Programování ve Windows
celé vláknoPro programování v C++ ve Windows platí:
"text" - ANSI („neunicode“) text (pro české Windows cp-1250)
L"text" - utf-16 text
Dále v knihovně tchar.h je nastaveno spousta maker, které na základě toho, zda je nebo není definováno UNICODE mapují typy/funkce na ANSI/UTF-16 variantu
_T("text") - pokud je definováno UNICODE, pak L"text" (UTF-16), jinak "text" (ANSI)
TCHAR - pokud je definováno UNICODE, pak wchar_t, jinak v (podobně: LPCTSTR, LPTSTR, PCTSTR, PTCHAR)
_tcslen, _tcscmp, _tcsdup, ...
V Linuxu jsem to nezkoušel, tam je vše UTF-8 (tj. bez problémů).

