Fórum Root.cz

Hlavní témata => Vývoj => Téma založeno: MilanC 20. 10. 2014, 11:35:41

Název: Podpora češtiny v jazyce C
Přispěvatel: MilanC 20. 10. 2014, 11:35:41
Zdravím Vás, a prosím o radu.
Učím se C, leccos už umím, ale pořád je toho méně, než toho, co neumím.
   Věřím tomu, že lze používat české znaky z jiné tabulky než ASCII, ale nějak se tomu samo nechce. Všemožné odkazy s vysvětlením vedou spíše jen na počeštění prostředí. S tím problém nemám ... printf("Ahoj světe!"); ... je v pořádku, v komentářích též používám svoji mateřštinu a desetinná čárka je opravdu čárkou.
   Jde ale o to, jak např. v souboru spočítat počet písmen s diakritikou - 'a' lze, 'á' právě nelze. Tuším, že nějaký složitější způsob s pomocí řetězců a polí by fungoval, ale tyto techniky ještě plně vědomě nepoužívám, neboť až tam jsem v učebnici zatím nedošel. Nicméně, nechci obcházet problém. Z principu věci bych očekával stejnou jednoduchou možnost práce se znaky, jakou mají Američani. Příklad:

Kód: [Vybrat]
/* Čeština */
#include <locale.h>
#include <stdio.h>
int main()
{
   setlocale(LC_ALL, "");

   printf("Řečiště široké %.1fm\n", 3.5);     /* ano */
   printf("á");                                              /* ano */
   putchar('a');                                           /* ano */
   putchar('á');                                           /* [b]NE[/b] */

   return 0;
}

Díky
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: Tomas 20. 10. 2014, 11:52:50
Cestinu do zdrojaku nedavej. Jedine prenositelne by bylo kodovani pomoci escape sequenci a UTF-8. To je ale uplny nesmysl, protoze se to neda cist. Proc nemuzes pouzit treba gettext a vychozi texty psat v anglictine? Pak budes mit produkt lokalizovatelny do cehokoliv.
Podle me prekladac neumi nastavit kodovani jako java, coz je tvuj problem a pouziva ASCII.
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: Tomas 20. 10. 2014, 11:56:07
Cestinu do zdrojaku nedavej. Jedine prenositelne by bylo kodovani pomoci escape sequenci a UTF-8. To je ale uplny nesmysl, protoze se to neda cist. Proc nemuzes pouzit treba gettext a vychozi texty psat v anglictine? Pak budes mit produkt lokalizovatelny do cehokoliv.
Podle me prekladac neumi nastavit kodovani jako java, coz je tvuj problem a pouziva ASCII.
Jo a ohledne toho pocitani znaku v souboru. Nektere znaky ti prave nefunguji, protoze je pravdepodobne kodovan jako utf-8 kde nektere znaky maji vice bajtu. Vyguugli si format a delku retezce si pak naimplementuj sam. strlen nefunguje. Druha moznost je prevest do unicode (short misto char) a pak pouzit prislusnou wide variantu strlenu.
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: Kolemjdoucí 20. 10. 2014, 11:57:25
Napřed je nutno zjistit v jakém kódování je ten soubor s češtinou, podle se rozhodne o postupu.
Na výběr je namátkou CP-852, Windows-1250, ISO-8859-2, UTF-8, ale jsou i jiné.
První tři by se zpracovávají prostým porovnáváním char s určitou hodnotou, číselná hodnota "á" je zde:

http://en.wikipedia.org/wiki/Code_page_852
http://en.wikipedia.org/wiki/Windows-1250
http://en.wikipedia.org/wiki/ISO/IEC_8859-2

Ve Windows je to ještě komplikované tím, že GUI aplikace používají Windows-1250, ale konzole z historických důvodů CP-852, takže znak co napíšeš do zdrojáku se v konzoli vypíše jinak.
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: gamer 20. 10. 2014, 12:21:47
Jestli si nechceš jen hrát, ale potřebuješ něco funkčního a ověřeného, tak použij ICU knihovnu:
http://site.icu-project.org/
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: ehm 20. 10. 2014, 12:25:50
matne vzpominam: -l wcs, i18n
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: eMko 20. 10. 2014, 16:29:15
Přímo v jazyku C pro to podpora není. Není důvod, aby byl.

Ve standardní knihovně jazyka C také ne - autoři se ji snažili udržet minimalistickou, od r. 1972 se zas až tak extra nezměnila.

Buď si hraj s kódováním znaků, což zpravidla podporuje operační systém nebo s nějakou knihovnou - po internetu se jich válí celkem dost. Např. GLib https://developer.gnome.org/glib/stable/glib-Character-Set-Conversion.html
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: EsoRimer 20. 10. 2014, 17:00:11
Problém kódování je dobře vysvětlený tady:
http://www.sallyx.org/sally/c/ (http://www.sallyx.org/sally/c/) (Znakové sady a Konverze znakových sad)
a tady iconv:
http://www.sallyx.org/sally/c/linux/ (http://www.sallyx.org/sally/c/linux/) (Základní linuxové funkce II)

Musíš se tam sice zaregistrovat, ale je to zadarmo :-)
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: MilanC 21. 10. 2014, 17:14:21
Děkuji Vám za tipy, ale u mě je to na dlouho.
   Prosté kódování znaků, pokud něco neopomíjím a má představa není zkreslená, tak funguje pouze do čísla 127. (Běží mi linux mint, jestli to s tím také souvisí)

Kód: [Vybrat]
printf("\u00e1");   dá   á
putchar('u00e1');   dá   ??
i = '\xe1';
printf("%d %c", i, i);   dá   ??

Jinak, nejde jen o písmenka v určitém kódování v souboru, ale o výstup na obrazovku - terminál v geany. Zkoušel jsem prohodit v nastavení utf8 za iso88592, a funguje to stejně.
   ICU jsem zatím nerozchodil, ale umí opravdu "primitivním" jednoduchým způsobem pracovat se znaky s diakritikou, nebo jde jen opět o prostředí?
      Na gettext() přijde ještě asi řada.
Zřejmě to ale vyhraje nějaká ta knihovna (Glib), kterou musím nejdřív pochopit.
   Sallyx mi zatím nic nedává, příklady na kódování nejsou pro začátečníka.
Hezký den!
 :'(
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: Kolemjdoucí 21. 10. 2014, 18:09:45
Zkus tohle a dej vědět co to vypsalo, tím se zjistí jaké kódování používáš.

char c = 0xE1;
putchar(c);

wchar_t wc = 0xE1;
putwchar(wc);
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: gamer 21. 10. 2014, 19:02:31
   ICU jsem zatím nerozchodil, ale umí opravdu "primitivním" jednoduchým způsobem pracovat se znaky s diakritikou, nebo jde jen opět o prostředí?

ICU to primitvním a jednoduchým způsobem neumí, protože žádný jednoduchý a primitivní způsob na práci s diakritikou neexistuje. Pokud chceš s diakritikou dělat něco rozumného, tak dřív nebo později skončíš u unicode a třeba takové UTF8 kódování má proměnnou délku znaku (1 až 6 bajtů), takže když to chceš zpracovávat, musíš si napsat parser, který ze sekvencí bajtů udělá jednotlivé znaky. Tohle a mnohem víc věcí za tebe řeší ICU. Nějaký elementární příklad, jak začít s ICU, jsem dával sem:
http://forum.root.cz/index.php?topic=9041.msg94125#msg94125
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: MilanC 22. 10. 2014, 02:43:49
Takže,
při tomto zadání:
   char c = 0xE1;
   putchar(c);
není na řádku nic.

Při tomto zadání:
   wchar_t wc = 0xE1;
   putwchar(wc);
se vypíše krásný nijak nepodbarvený otazník, jako kdyby tomu náležel. Takový se ale zjeví i při jiných vyšších číslech.

   Když zadám všechny čtyři tyto řádky, tak se ve výsledku ukáže podbarvený (inverzní) otazník.  Při nižších číslech se vypisují různé znaky.
Jinak, v úvodu programu jsem měl zavolán taky tento soubor wchar.h.
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: Kolemjdoucí 22. 10. 2014, 08:37:14
Pravděpodobně tedy používáš UTF-8

http://en.wikipedia.org/wiki/UTF-8

A to by mělo fungovat toto, to je "á" jako UTF-8.

printf("\xC3\xA1\n");
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: wheel inventor 22. 10. 2014, 10:51:48
Druha moznost je prevest do unicode (short misto char) a pak pouzit prislusnou wide variantu strlenu.

Pozor, short byva vetsinou 16 bitovy a unicode pouziva 21 bitu
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: eMko 23. 10. 2014, 07:33:33
Ano a proto jsou definovány typy jako wchar_t . Je dobré je používat ;-)
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: Jetset 23. 10. 2014, 15:43:17
Musis si dat pozor, abys mel zdrojak i system v kodovani UTF8. Pak budou fungovat veci jako printf("áááááá");
putchar ti fungovat NIKDY nebude, protoze putchar vypise JEDEN BYTE, ne jeden znak. Znak je v tomto pripade sekvence az sesti bytes. Mel by fungovat putwchar, jak tady uz nekdo zminil, ale osobne jsem ho nikdy nepouzil, tak nevim. Davej si pozor pri read/write do file, pokud ocekavas, ze by ve file melo byt jine kodovani, musis prekodovavat.
Co se tyce zjistovani delky retezce, staci si na to napisat funkci, ktera bude pocitat vsechny znaky ktere jsou mensi nez 0x80 NEBO vetsi nez 0xbf (hodnoty 0x80 az 0xbf se pouzivaji v pripade vicebytovych sekvenci jako druhy a dalsi znak).
Pro vyhledani znaku v retezci muzes pouzit funkci strstr a vyhledavat string - opakuji, ze ne-ascii znaky nejsou jeden byte, ale de-facto string, takze strstr("máma má maso", "á") ti to najde.
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: MilanC 25. 10. 2014, 13:08:22
Tak už to mám,
nejdřív, díky za rady, ale řešení je zdá se jednoduší.
Připomenu jen o co mi šlo, jakožto pořád ještě začátečníkovi: ne o toto
   printf("á");   , což funguje zřejmě v každém dobře nastaveném národním prostředí, ale o tohle
   c = 'á';
   printf("%c", c);   , o všemožnou práci s jakýmkoli znakem, což, souhlasím, nejde.
A jak to tedy jde?

S širokými znaky mi funguje následující:
   <wchar.h>
   wchar_t wc;
   wc = "žšč";
   printf("%s", wc);
Tento způsob ale nedokáže číst z nějakého důvodu z obrazovky nebo ze souboru.

Nebo
   char s[] = "žšč";
   printf("%s", s);

A o to mi především pro začátek šlo. I když teď mě čeká, ano, umět hledání řetězce v řetězci atd.
   Koukám taky, že to nenačítá mezery a nic po nich. Holt to je další schůdek přede mnou v mém procesu učení se C.
Mějte se ... programátorsky.
Název: Re:Podpora češtiny v jazyce C
Přispěvatel: dword 25. 10. 2014, 14:01:05
#include <wchar.h>

wchar_t *str1 = "žšč";
wchar_t str2[] = "žšč";
wchar_t char1 = 'ž';

wprintf("%s", str1);
wprintf("%s", str2);
putwchar(char1);
wprintf("%c", char1);