Stránka 1 z 1

Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 12:38
od Rihl
Nazdar,
mám tu malý problém. Ve Windows,když : zkompiluju program v Céčku ,kterej má unicode znaky nebo zavolám batch script s Unicode,tak to dopadne nějak takhle:

Příliš žluťoučký kůň úpěl ďábelské ódy
|
V
P°ÝliÜ ×luŁouŔkř k¨˛ ˙pýl ´ßbelskÚ ˇdy

V Linuxu žádný z těchto problémů nepociťuji,takže je zase vidět rozdíl mezi "plnohodnotně českými" Windowsy a "pouze přeloženými" Linuxy.
Zkoušel jsem spustit cmd jako cmd /U (prý to má zajistit podporu Unicode) a ukládat zdrojové soubory ve všech možných kódováních(ANSI,Unicode,Big Endian, UTF-8) , ale pokaždé to vyšlo stejně.Nevíte,jak by to šlo vyřešit?

Jo,ještě mám jeden problem s Unicode:
existuje v Céčku nějaká strktura,která by umožňovala Unicode jako jeden char? když totiž napíšu:

Kód: Vybrat vše

...
char str[]=ěščřžýáí;
printf ("%d",strlen(str));


vyjde mi délka jako 16 místo osmi. Vím, čím to je a proto se ptám jestli není nějaká struktura,která by mohla určovat pro jeden znak jedno místo ( když potom napíšu printf ("%c",str[5]) , vypíše to otazníček namísto písmena) ,takže bych mohl přistupovat k jednotlivým znakům.

Jestli někdo aspoň trochu pochopil, co to tady mektám , ať prosím odepíše :D

Re: Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 13:38
od faraon
Z toho si nic nedělej, Windows má prostě v kódování znaků schizofrenii. Interně sice jede v UTF-16, ale dokumenty se obvykle ukládají ve Win-1250. A příkazový řádek do toho ještě matlá prehistorické IBM-852 z dob MS-DOSu, ale zrovna na to se nedá spolehnout. Tenkrát se navíc používalo normalizované KOI-8CS, ale nejrozšířenější na PC bylo kódování bratří Kamenických, do toho Apple měl samozřejmě svoje vlastní, Amiga... Jó, to byly časy :lol:
Podobné problémy bys měl i na starších linuxových distrech, které používaly třeba ISO 8859-2, mám pocit jestli v něm dodnes nejede třeba Slax.
Programy pro Windows prostě nestačí přeložit, ale musí se navíc "lokalizovat", tedy překódovat do patřičné osmibitové znakové sady, a nebo použít pro výpis nějakou widloidní knihovnu místo standardní, čímž okamžitě skončí přenositelnost tvého programu. Leda bys použil podmíněný překlad :-( U toho skriptu je to jednodušší, stačí ho otevřít v textovém editoru v příslušném kódování a nechat uložit v jiném, kdysi když to ještě neuměl Notepad, tak jsem takové věci dělal přes IE.

Kromě char existuje také wchar, a například příkaz wprintf, potřebuješ k tomu knihovnu wchar.h Ale co vím z doslechu, jsou s tím nějaké problémy.

Re: Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 13:49
od Rihl
např.:Já programuju v Pythonu , kde mám program,který pracuje s jednotlivými znaky v řetězci. Jedna jeho část je ale kriticky pomalá,a tak mně napadlo,že to napíšu v Céčku. Poté,co jsem to teda nějak rozjel,jsem zjistil přesně tento problém. Když jsem měl prostě

Kód: Vybrat vše

char str[]="unikód" ;
printf ("%c",str[5]); //mělo by to napsat ó

napsalo to v Linuxu otazníček a ve Windows nějaký velmi zvláštní symbol. Vím,že je to proto,že unicode se nevejde do 8 bitů,proto je jakoby rozdělen na dva znaky ( takže by to muselo být printf("%c%c",str[5],str[6])).To jsem alespoň vyrozumněl. Takže pokud chci,aby to unicode znak počítalo jako jeden znak,musí být řetězec definován jako wchar ?

Jinak : díky za rychlou odpověď

Re: Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 14:47
od faraon
Problém je v tom že řetězec "unikód" je v paměti uložený jako [u][n][i][k][Ă][ł][d][\0], takže znak [5] bude vypisovat jen to "ł". Pak záleží na tom jaké kódování používá výstupní zařízení a jak to pobere, jestli zobrazí nějaký jiný znak nebo chybu (ten otazníček). Bacha na to že v C je pole indexované od nuly, takže páté písmeno "ó" by bylo [4]+[5]. Ovšem zase jen za předpokladu že před ním budou jen jednobajtové znaky, jinak se pošoupne dál :huh:

Ano, wchar bere celé Unicode znaky najednou, ale je tam ještě jeden problém, a to že na Linuxu má typ wchar 32 bity, zatímco na Windowsu jen 16. Navíc na tom Windowsu budou nejspíš fungovat s UTF-16, ale na Linuxu s UTF-8, což je dost veliký rozdíl. I když možná to UTF-8 bude převedené do UTF-32 :shock: Ještě jsem se nedonutil to zkusit, abych vlastně přesně věděl jak to funguje, zatím jsem si naštěstí nějak vystačil s tím co se dá udělat běžnou cestou.

A to buď rád že programuješ v Čechách a ne v Číně, protože čínské znaky mají čtyři bajty 8) a navíc v UTF-8 může mít každý znak délku od jednoho do šesti bajtů! I když novější norma to omezila na čtyři, ale pár let to platilo a nikdo nezaručí že se to v budoucnu zase nezmění.



Doplnění: tohle by ti mohlo být užitečné: http://www.fit.vutbr.cz/~lampa/locale/localizace4.html Sice poněkud staršího data, zato v češtině :) Trochu jsem se s tím potrápil, ale nějak to chodí. Akorát se mi fputws nesnáší s klasickým printf, co použiji první to funguje, druhé nevypisuje nic.

Kód: Vybrat vše

#include <locale.h>
#include <stdio.h>
#include <wchar.h>

#define VELIKOST 100

int main(void)
{
    wchar_t veta[VELIKOST],
           hura[]={L"HURÁ"};

    setlocale(LC_ALL,"");

    fgetws(veta,VELIKOST,stdin);
    fputws(veta,stdout);
    fputwc(veta[1],stdout);
        putwchar('\n');

    fputws(hura,stdout);
        putwchar('\n');
    fputwc(hura[3],stdout);
        putwchar('\n');
   

    return 0;
}

Výsledek:
faraon@tuxbox:/home/faraon/c/wchar$ ./a.out
asd
asd
s
HURÁ
Á
faraon@tuxbox:/home/faraon/c/wchar$ ./a.out
ěšč
ěšč
š
HURÁ
Á

Když jsem tam neměl to setlocale, tak to nechodilo vůbec, čtení skončilo u prvního znaku s diakritikou! Takhle to pracuje, ale pokud bys chtěl používat třeba řazení podle abecedy, musel bys tam zadat nějaké konkrétní hodnoty.

Re: Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 20:55
od Rihl
Děkuju moc, bohužel teďka se k tomu nedostanu,ale až,tak pořádně. Problém je,že program píšu v Linuxu, a ve windows ho pak jenom zkompiluju. Holt to pak budu muset trochu poupravit. Na to,že se v céčku indexuje od nuly,jsem pozapomněl, takže díky za opravu ;)
To, že nejsem Číňan, jsem rád, protože jsem zkoušel např znak U+3456 ( něco čínského) a ten měl délku 3 znaky. Takže guláš !

OffTopic: Všiml jsem si,že jsi taky Linuxák( a nejen podle avataru ;) ! Jaká distribuce?

Edit:
Tak ve woknech tak poloviční úspěch. nejdřív mi to vypisovalo :
test.c:10:20: converting to execution character set: Invalid argument
řádek 10 je:

Kód: Vybrat vše

           hura[]={L"HURÁ"};

zjistil jsem,že když z HURÁ udělám HURA,jde to. Zase:změna kódování nefunguje.
Když jsem to takto změnil,už to byla hračka zkompilovat a spustit. Ale:

ěščřžýáíé
Řçźý§ě ˇ'
ç
HURA
A

Index funguje správně. Ale psaní na stdout nějak nefunguje(normální printf by to napsal správně - kupodivu) - píše to nějak přeházeně(jako předtím)
Takže úspěch tak 50-50

Re: Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 21:34
od faraon
Jójo, jak to bylo všechno jednoduché, když se dalo vystačit se sedmibitovým ASCII :listen:
Jedu na Ubuntu 6.06, trochu vykopávka, ale na ty já si docela potrpím:

Didaktik Gama.jpg

Re: Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 21:48
od Rihl
To mi připomíná nějakou složitější obměnu BASICu. Nemám pravdu?

Jo,a aby jsem neměl úplně offtopic:
ěščřžýáíé
|
V
Řçźý§ě ˇ'

má na svědomí
prehistorické IBM-852 z dob MS-DOSu
, nebo nějaká další "chyba,za kterou se platí" vymyšlená zaměstnanci MikroŠrotu?

Re: Unicode v C a v batch scriptech?

Napsal: 13 úno 2011 22:46
od faraon
Je to nějaké divné, když ěščřžýáíé uložíš jako Win-1250 a konzole to zobrazí v IBM-852, mělo by tam být ýÜŔ°×řßÝÚ.
Když to uděláš přesně opačně, tedy soubor je v kódování IBM-852 a Windows se ho pokouší zobrazit jako Win-1250, vyjde ti Řçźý§ě ˇ‚ - takže to co máš. Tak to ulož ve Win-1250 a snad to zobrazí správně.
Co si vzpomínám, tak u XPček se někdy zaplo IBM-852 a někdy ne, záleželo jestli se příkazový řádek spustil v okně nebo přes celou obrazovku.
Našel jsem tabulku se spoustou těch kódování: http://mlha.cz/unicode/

Je to Sinclair BASIC na Didaktiku Gama, slovenské kopii Sinclairu ZX-Spectrum. A že by byl složitější bych neřekl, šetřili tam každým příkazem, ale tak promyšleně že se s tím daly dělat hotové divy :twisted: Tenhle prográmek vypíše všechny kombinace barev které to umělo, to je ta tabulka vlevo nahoře, potom se vylistuje zdrojový kód, a nakonec se přes něj nakreslí ta kytka. Rozlišení obrazovky 256x192 bodů, v BASICu se dalo použít jen 256x176, v osmi barvách a dvou úrovních jasu :-D

Re: Unicode v C a v batch scriptech?

Napsal: 14 úno 2011 15:57
od Rihl
Takže,musel jsem nainstalovat gedit pro windows a zpřeházet trochu setlocale v kódu,ale nakonec to fungovalo:

Kód: Vybrat vše

#include <locale.h>

#include <stdio.h>

#include <wchar.h>



#define VELIKOST 100



int main(void)

{

    wchar_t veta[VELIKOST],

           hura[]={L"HURÁ"};


    fgetws(veta,VELIKOST,stdin);


    fputws(veta,stdout);

    fputwc(veta[1],stdout);

        putwchar('\n');

    setlocale(LC_ALL,"");

    fputws(hura,stdout);

        putwchar('\n');

    fputwc(hura[3],stdout);

        putwchar('\n');

   



    return 0;

}


To jsem musel přes gedit uložit do UTF-8 ( v notepadu to samozřejmě nešlo) a zkopilovat. Výstup:

čřžýáí
čřžýáí
ř
HURÁ
Á

S originálním kódem to bylo nějak takhle:

řžýáé
ý§ě '
§
HURÁ
Á

tahže problém je v setlocale(když jsem smazal řádek s setlocale,šel vstup ,ale HURÁ to psalo jako HUR┴ ). Prostě Windows.

EDIT:Našel jsem to!

Kód: Vybrat vše

...
setlocale(LC_ALL,"Czech_Czech Republic.OCP");
...

nebo:

Kód: Vybrat vše

...
setlocale(LC_ALL,"Czech_Czech Republic.852")
...

852 je asi to "prehistorické IBM852 z dob MsDOSu",což by vše vysvětlovalo! Takže když to shrnu:
1)stáhnout gedit z http://live.gnome.org/Gedit/Windows
2)napsat program(klidně i v notepadu nebo v libovolném vývojovém prostředí)
3)otevřít v geditu,Soubor>Uložit jako...>a z kódování UTF-8
4)zkompilovat(MinGW)

Re: Unicode v C a v batch scriptech?

Napsal: 14 úno 2011 17:28
od CZechBoY
setlocale je PHP funkce ne? :D

Re: Unicode v C a v batch scriptech?  Vyřešeno

Napsal: 14 úno 2011 17:50
od Rihl
Taky,ale je i v Céčku v knihovně locale.h

Takže: Vyřešeno,děkuju

Linux 4ever!!