abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
včera 20:00 | Nová verze

Byla vydána (YouTube) verze 2018.3 multiplatformního herního enginu Unity (Wikipedie). Přehled novinek i s videoukázkami v příspěvku na blogu a v poznámkách k vydání.

Ladislav Hagara | Komentářů: 0
včera 19:33 | Nová verze

Byla vydána verze 18.12.0 KDE Aplikací (KDE Applications). Přehled novinek v kompletním seznamu změn a na stránce s dalšími informacemi. Správce souborů Dolphin umí nově například zobrazovat náhledy dokumentů vytvořených v LibreOffice a aplikací ve formátu AppImage. Konsole plně podporuje obrázkové znaky emoji. V Okularu lze k pdf souborům přidávat poznámky.

Ladislav Hagara | Komentářů: 2
včera 17:11 | Nová verze

Byla vydána nová stabilní verze 2.2 (2.2.1388.34) webového prohlížeče Vivaldi (Wikipedie). Z novinek vývojáři zdůrazňují například vylepšení správy listů - vybrané listy lze uložit jako relaci, možnost zobrazení klávesových zkratek určených webovou stránkou nebo možnost přehrávání videí v režimu obrazu v obraze. Nejnovější Vivaldi je postaveno na Chromiu 71.0.3578.85.

Ladislav Hagara | Komentářů: 3
včera 14:22 | Nová verze

Po 4 měsících vývoje od vydání verze 3.0.0 byla vydána nová verze 3.1.0 otevřeného emulátoru procesorů a virtualizačního nástroje QEMU (Wikipedie). Přispělo 189 vývojářů. Provedeno bylo více než 1 900 commitů. Přehled úprav a nových vlastností v seznamu změn.

Ladislav Hagara | Komentářů: 0
včera 01:32 | Nová verze

Letos bylo v komunitě Mageia hodně změn. Po volbě nových vedoucích přišla velká aktualizace a krátce na to udržovací verze 6.1. 7.12., dle plánu, vyšla Mageia s číslem 7 v její první beta verzi. Chyby můžete hlásit v bugzille. Chyby v českých překladech pak na fóru české komunity.

Joelp | Komentářů: 0
včera 00:11 | Zajímavý projekt

Kvůli rychlejšímu vývojovému cyklu byla přemístěna Cinelerra-gg. Cinelerra-gg je fork Cinelerry-hv. Některé rozdíly forků popisuje sám hlavní vývojář William Morrow (aka GoodGuy). Není zde popsán i fork Lumiera, zřejmě kvůli zatím nepoužitelnému stavu.

… více »
D81 | Komentářů: 0
12.12. 19:11 | Nová verze

Do aplikace pro instant messaging Telegram (Wikipedie) lze nově nahrát češtinu. Více v příspěvku na blogu Telegramu.

Ladislav Hagara | Komentářů: 5
12.12. 10:55 | Nová verze

Jean-Baptiste Kempf, prezident neziskové organizace VideoLAN stojící za svobodným multiplatformním multimediálním přehrávačem a frameworkem VLC, oznámil v příspěvku na svém blogu vydání první oficiální verze 0.1.0 v říjnu představeného dekodéru svobodného videoformátu AV1 (AOMedia Video 1) s názvem dav1d (Dav1d is an AV1 Decoder). Jedná se o alternativu k referenčnímu dekodéru libaom. Kódový název dav1da verze 0.1.0 je Gazelle.

Ladislav Hagara | Komentářů: 3
12.12. 10:22 | Nová verze

Po více než dvou letech od vydání verze 11.0 byla vydána nová major verze 12.0 svobodného unixového operačního systému FreeBSD. Podrobný přehled novinek v poznámkách k vydání.

Ladislav Hagara | Komentářů: 4
11.12. 19:55 | Nová verze

Byla vydána verze 3.11 živé linuxové distribuce Tails (The Amnesic Incognito Live System), jež klade důraz na ochranu soukromí uživatelů a anonymitu. Přehled změn v příslušném seznamu. Řešena je řada bezpečnostních chyb.

Ladislav Hagara | Komentářů: 0
Chystáte se přejít na Wayland na „desktopu“?
 (25%)
 (6%)
 (12%)
 (31%)
 (26%)
Celkem 123 hlasů
 Komentářů: 17, poslední včera 23:57
Rozcestník

Programátorská hádanka 4 - céčkovská zrada

26.8.2010 19:00 | Přečteno: 1648× | poslední úprava: 26.8.2010 22:14

Už dlouho nevyšla žádná programátorská hádanka, tak to musím napravit :-) Dnes bude trochu lehčí než minule. Setkal se s tím určitě každý, kdo alespoň přičuchnul k C nebo C++.
Mám funkci Trim() pro ořezávání bílých znaků ze začátku a z konce textu. Když tedy např. dostane řetězec „ lenochod na pochodu\n“, vrátí „lenochod na pochodu“. Za bílý znak pro jednoduchost považuji znaky jen s ASCII hodnotou menší nebo rovno než mezera (tedy mezeru a řídící znaky). Funkce přímo přepisuje vstupní řetězec; vzhledem k tomu, že se ořezáním řetězec nikdy neprodlouží, může si to dovolit.

Zde je již kód:

void Trim(char *str) {
  int zleva;     //kolik bílých znaků zleva oříznu
  for (zleva = 0; str[zleva] != '\0'; zleva++) {
    if (str[zleva] > ' ') break;
  }

  int i;      //zkopíruju zbytek řetězce
  for (i = 0; str[i+zleva] != '\0'; i++) {
    str[i] = str[i+zleva];
  }
        //najdu konec řetězce
  for (i--; i >= 0 && str[i] <= ' '; i--);

  str[i+1] = '\0';		//a oříznu
}

Celkem krátký kód, poměrně lehký, skoro školní úloha. Nicméně, tato funkce nepracuje správně :-) obsahuje minimálně 2 různé chyby, které způsobují, že existuje vstup, pro který nedává očekávaný výstup.

Najdete je? ;-) Ještě dodávám, že kód můžete i debugovat, ačkoli vám to pravděpodobně moc nepomůže.

Domněnky a řešení pište do komentářů. Vy ostatní se při přemýšlení samozřejmě do komentářů nedívejte ;-)

Řešení:
Na správné řešení přišel Ondrej 'SanTiago' Zajicek.

První chyba je, že typ char je znaménkový, takže znaky >= 128 (typicky znaky s diakritikou, v libovolném kódování) jsou vlastně záporné. Z tohoto důvodu neprojdou podmínkou if (str[zleva] > ' ') a jdou uřezány společně s bílými znaky. Je to trochu od jazyka C/C++ zrada; sice je znaménkový typ konzistentní se standardní „znaménkovostí“ jiných typů, ale u řetězců toto nemá význam; neumím si představit, kdy bych využil, že ASCII >= 128 je reprezentováno zápornými hodnotami. Naopak je mnoho případů, kdy dochází k chybám a podivným nelogičnostem (viz např. tato ukázka). V Javě jsou třeba všechny typy striktně znaménkové, ale typ char je jediný neznaménkový (16bitový). Taktéž i jiné jazyky nikdy neberou znak jako záporné číslo.

Druhou chybou je použití typu int k indexování. Typ int je 4bajtový (nebo 2bajtový v 16bitovém prostředí) a nehodí se tak pro adresaci paměti. K adresaci paměti je vhodné použít typ size_t (neznaménkový) nebo ptrdiff_t (znaménkový). Tyto typy tak veliké, jak veliký je ukazatel; na 32bitovém mají 4 bajty, na 64bitovým 8 bajtů. V tomto případě by se program v 64bitovém prostředí zacyklil na prvním cyklu při 2 GiB dlouhém řetězci. Na 32bitovém prostředí by pak neořízl řetězec zprava (hned by vyskočil z třetí podmínky).        

Hodnocení: 75 %

        špatnédobré        

Anketa

Jak těžká je tato hádanka?
 (10 %)
 (0 %)
 (3 %)
 (6 %)
 (11 %)
 (70 %)
Celkem 63 hlasů

Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

Komentáře

Vložit další komentář

vlastikroot avatar 26.8.2010 19:21 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Sakra! Obě jsem našel, až když jsem zahlasoval, že nevidim ani jednu:-D
Sg1-game | We will destroys the Christian's legion ... and the cross, will be inverted | IP 80.188.182.6
vlastikroot avatar 26.8.2010 19:28 vlastikroot | skóre: 24 | blog: vlastikovo | Milevsko
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ne, spíš to vypadá, že vidim chyby tam, kde vlastně nejsou.
Sg1-game | We will destroys the Christian's legion ... and the cross, will be inverted | IP 80.188.182.6
Aleš Janda avatar 26.8.2010 20:17 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Tak napiš, které vidíš :-)
26.8.2010 19:51 jas | skóre: 13 | blog: blag
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Staci NULL a "" alebo sa nad tym treba skutocne zamysliet (a najst este treti vstup)?
26.8.2010 19:58 Semo | skóre: 44 | blog: Semo
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
NULL nechapem ako vstup, ktory nefunguje. Ako by si definoval trimovanie? A bud blbo vidim alebo "" zbehne ok. Ale napr "   " nezbehne ok - neotrimuje
If you hold a Unix shell up to your ear, you can you hear the C.
Aleš Janda avatar 26.8.2010 20:19 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Více mezer také otrimuje - ořízne to ten příkaz úplně na konci, protože 'i' tam bude -1.

NULL není platný vstup, takže to na něm zhavaruje (a je to správně) - to neberu jako chybu.
26.8.2010 20:24 Semo | skóre: 44 | blog: Semo
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ha, vravel som ze blbo vidim, nevsimol som si ";" na konci 2. for cyklu.
If you hold a Unix shell up to your ear, you can you hear the C.
26.8.2010 19:54 maddoxik | skóre: 8 | blog: maddoxikovo
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Nejsem programator, ale tipnul bych, ze se nekontroluji meze, takze v pripade hooooooodne dlouheho retezce pretece promenna zleva a pak dohavaruje ten druhy cyklus, protoze index i bude zaporny.
Aleš Janda avatar 26.8.2010 20:20 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Jsi blízko jedné z chyb ;-)
26.8.2010 20:24 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ono by to chtelo definovat co je validni vstup.
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
26.8.2010 20:30 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
A taky jestli to ma delat to co je napsano v zadani, nebo opravdu Trim.
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
Aleš Janda avatar 26.8.2010 20:35 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Validní vstup je jakýkoli řetězec typu char*, neNULLová hodnota, ukončená '\0'. Může být i prázdný.

Ořezávají se všechny řídící znaky ASCII < 32 a mezera. Myslel jsem, že je to standardní chování trimu, teď vidím, že např. PHP standardně ořezává jen některé řídící znaky, ale to je víceméně jen detail.
26.8.2010 20:37 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
No, ono totiz < 32 je neco jineho nez 0..32
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
26.8.2010 20:04 sivlk | skóre: 15 | blog: sivlk
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ako mam hlasovat ked som nasiel 3 chyby?
Aleš Janda avatar 26.8.2010 20:20 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Jaké?
26.8.2010 21:05 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
1) Indexuje mimo meze na vstupu slozenym ze samych mezer.

2) trimuje i znaky s nahozenym nejvyssim bitem, protoze char je obvykle interpretovan jako signed.

3) Na 64bit Linuxu se zacykli se na stringu delsim nez 4 GB :–)
Aleš Janda avatar 26.8.2010 21:16 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
1) Indexuje mimo meze na vstupu slozenym ze samych mezer.

Proč myslíte? V kterém cyklu?

2) trimuje i znaky s nahozenym nejvyssim bitem, protoze char je obvykle interpretovan jako signed.

Gratuluji, toto je ta první chyba :-)

3) Na 64bit Linuxu se zacykli se na stringu delsim nez 4 GB :–)

A gratuluji znova, toto je ta druhá chyba :-) konkrétně se zacyklí i na stringu delším než 2 GiB, a tedy i na 32bit :-)
26.8.2010 21:24 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
konkrétně se zacyklí i na stringu delším než 2 GiB, a tedy i na 32bit
Opravdu se rozbije i na 32bit systemu? Nejsem si teda presne jist, jak se chova pointerova arimetrika pri preteceni, ale tipoval bych ze to vezme modulo 2^32, takze se to bude prakticky chovat jako by byl index unsigned.
26.8.2010 21:28 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
V takovem pripade by se na 32bit systemu na souboru vetsim nez 2 GB chovala spatne az treti smycka (skoncila by ihned), coz je trochu jiny pripad nez na 64bit systemu (indexace mimo meze v prvni smycce), takze to lze klasifikovat jako dve ruzne chyby. ;–)
Aleš Janda avatar 26.8.2010 22:00 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Máte pravdu, po větším zamyšlení vlastně je to přesně tak - na 32bitech by to vlastně „náhodou“ fungovalo, ale rozbilo se to až dál. Zajímavé, jak je to vlastně zmatečné.

Každopádně jste přišel na obě chyby, gratuluju :-)
26.8.2010 22:25 mich | skóre: 16
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Nejspíš je to hodně hloupá otázka, ale přesto jí položím. Jak alokujete místo pro retezec vetsi nez maximalni hodnota size_t (=int)?
je to teď v módě, na žive o tom furt píšou
Aleš Janda avatar 26.8.2010 22:30 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Int je znaménkový, čili max. kladný index je 2^31. Funkce malloc přitom bere size_t, což je neznaménkový, čili 2^32 (na 64bit 2^64). Neplatí tedy, že int = size_t; myslím, že bych alokovat 3 GB klidně mohl.
26.8.2010 21:18 Ondrej 'SanTiago' Zajicek
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Tak u 1) jsem se taky nechal nachytat, tohle zrejme funguje.

Upresneni k 3) - vzhledem k signed indexu to selze uz na 2 GB stringu indexovanim mimo meze.
26.8.2010 20:06 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
str[i+1] = '\0'; je out of bounds pro prazdny retezec a taky to nefunguje pro retezce ktere jsou jenom z bilych znaku

Netusim jestli to je jedna nebo jsou to dve chyby.
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
26.8.2010 20:10 Let_Me_Be | skóre: 20 | blog: cat /proc/idea/current | Brno
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Hmm, tak jsem se nechal nachytat.
Linked in profil - Můj web - Nemůžete vyhrát hádku s blbcem. Nejdřív vás stáhne na svoji úroveň a pak ubije zkušenostmi.
26.8.2010 20:14 Jarda
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
void Trim(char **str)?
26.8.2010 20:17 Jarda
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ale nic, zacatek se nemeni.
26.8.2010 20:23 R
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Nielen, ze je to zle, ale este to je aj neefektivne - kopiruje sa kus retazca, ktory sa hned potom zahodi.
26.8.2010 20:39 Filip Jirsák | skóre: 67 | blog: Fa & Bi
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Okopírovat se to dá taky efektivněji než to posouvat bajt po bajtu.
27.8.2010 19:18 Kvakor
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ano, je neefektivní kopírovat řetězec, který ještě není ořizlý zprava, stačilo by prvně provést oříznutí z obou stran a pak teprve kopírovat. Případně to celé nacpat do jednoho jediného cyklu, aby se zbytečně nezaplácávala cache.
26.8.2010 23:02 R
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Tu je najmenej jedna chyba:
void trim(char *str) {
  char *begin = str, *end;

  while ((unsigned char)*begin <= ' ' && *begin != '\0')
    begin++;

  end = begin + strlen(begin);
  while ((unsigned char)*end <= ' ' && end > begin)
    end--;

  memmove(str, begin, end - begin + 1);
  str[end - begin + 1] = '\0';
}
Aleš Janda avatar 26.8.2010 23:18 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Tak trochu mi to dalo zabrat :-) ale pokud má předaný buffer jen jeden bajt (a tam je koncová nula, čili prázdný řetězec, pak begin = end = str a tudíž poslední řádek zapíše 0 na index 1 => za buffer.
26.8.2010 23:38 __dark__
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ty chyby jsou zřejmé, ale teď je třeba se trochu zamyslet. Nepoužívá náhodou i Qt/Java/.NET typ int pro velikost a indexaci datových struktur? Možná tu máme omezení do budoucna;-)
29.8.2010 23:19 zulu
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Správně jsi napsal indexaci, zatímco autor píše o adresaci. K adresaci se int opravdu nehod, ale k indexaci náramně.
27.8.2010 07:58 kolcon | skóre: 15 | blog: kolcon
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Zlaty Perl a jednoduche reseni regexpem...
27.8.2010 08:18 Michal Kubeček | skóre: 71 | Luštěnice
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada

Přiznávám se bez mučení, že úvahu "považujme za bílý znak cokoli s kódem menším nebo rovným 32" jsem bral za natolik nesmyslnou, že jsem si prostě místo toho testu v duchu dosadil isspace() a chybu tudíž neodhalil, protože mne nenapadlo hledat chyták v podobě chybné implementace něčeho, co je samo o sobě chyba.

Mimochodem, určitě je podle normy char znaménkový? Vždycky jsem měl za to, že je na implementaci, jestli bude char totéž co signed char nebo unsigned char, a programátor by tudíž neměl předpokládat ani jedno.

27.8.2010 10:04 Karel Zak | blog: kzak
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Mimochodem, určitě je podle normy char znaménkový? Vždycky jsem měl za to, že je na implementaci, jestli bude char totéž co signed char nebo unsigned char, a programátor by tudíž neměl předpokládat ani jedno.
C99 6.2.5 Types

An object declared as type char is large enough to store any member of the basic execution character set. If a member of the *basic execution character set* is stored in a char object, its value is guaranteed to be nonnegative. If any *other character* is stored in a char object, the resulting value is *implementation-defined* but shall be within the range of values that can be represented in that type.

5.2.1 Character sets

Both the basic source and basic execution character sets shall have the following members: the 26 uppercase letters of the Latin alphabet, the 26 lowercase letters of the Latin alphabet, the 10 decimal digits, 29 graphic characters (pozn. zavorky, carky apod.)

.. tedy zakladni znaky lze predpokladat jako signed, ale vse ostatni je implementation-defined.

Dulezite je, ze to chovani je arch dependent, treba x86 GNU/Linux je signed, ale ARM je unsigned apod. Viz:

http://www.network-theory.co.uk/docs/gccintro/gccintro_71.html

Takze je vhodne bud kompilovat s -fsigned-char pokud trvate na tom, ze char ma nejake urcite znaminko. Jinak v kodu je vhodne pouzivat "char" jen tam kde se nepracuje se znaky, jinak striktne "unsigned char".

Aleš Janda avatar 27.8.2010 10:18 Aleš Janda | skóre: 21 | blog: kýblův blog | Kralupy nad Vltavou
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Joj, tak tohle je tedy opravdu zajímavé. O gcc přepínačích na znaménkovost jsem věděl, ale že je to na ARMu defaultně unsigned, to je pro mě novinka. Díky :-)
27.8.2010 10:29 R
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Skus si dat retazce ako unsigned char * a pouzivat funkcie ako strlen() - kolko tam budes mat warningov...
Jardík avatar 27.8.2010 22:33 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Se dá vždycky přetypovat :-)
Věřím v jednoho Boha.
27.8.2010 10:36 Martin Mareš
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
jsem si prostě místo toho testu v duchu dosadil isspace() a chybu tudíž neodhalil
Pozor, s isspace() vznikne velice podobná chyba – není ho totiž dovoleno volat se záporným argumentem.
Vždycky jsem měl za to, že je na implementaci, jestli bude char totéž co signed char nebo unsigned char, a programátor by tudíž neměl předpokládat ani jedno.
Přesně tak.
27.8.2010 23:57 rastos | skóre: 61 | blog: rastos
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Nedávno som stretol tiež takú hlúpu chybu. V jave som potreboval nájsť v reťazci A podreťazec B a podľa jeho pozície rozdeliť A na na časť, pred výskytom B, časť zhodnú s B a časť za výskytom B. Case insensitive. A práve tá case-insenstitivta bola riešená prevodom oboch stringov cez toUpper(). Fungovalo to fajn, až kým A neobsahovalo nemecké ostré "ß". To pri prevode cez String.toUpper() vyrobilo "SS" - čím A malo zrazu o jeden znak navyše a zrátané indexy boli tým pádom o jedna posunuté ;-) Vyriešené to bolo nakoniec cez regexp.
Jardík avatar 28.8.2010 01:36 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ze ß to vyrobilo SS? Jako z jednoho znaku dva? Nebo to vyrobilo z 1 charu (ve smyslu datového typu) chary 2 (to SS nějaký "spojený znak")? Protože java používá ke kódování řetězců UTF-16, bylo by to naprosto v pořádku a je třeba s tím počítat. Nesnáším algoritmy, co si myslí co jeden char (jako datový typ), to jeden znak.
Věřím v jednoho Boha.
28.8.2010 12:28 rastos | skóre: 61 | blog: rastos
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
"straße".length() vrátilo 6 ale "straße".toUpper().length() vrátilo 7, pretože "straße".toUpper() je "STRASSE" a to je 7 znakov.
28.8.2010 13:18 Martin Mareš
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
Ze ß to vyrobilo SS? Jako z jednoho znaku dva?
Pokud ano, tak to jednalo zcela podle standardu: UniCode (alespoň ve verzi 5.0, do které zrovna koukám) ve svých case mappings opravdu definuje, že 00DF (German es-zed) má jako upper case 0053 0053 (SS). A stejně se, tuším, chová i německý pravopis.
Jardík avatar 28.8.2010 17:20 Jardík | skóre: 40 | blog: jarda_bloguje
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
A jsou to opravdu 2 znaky, nebo je to surrogate pair? Já to unicode nestuduji, ale pokud v řetězci takový znak je, tak String.length nevrátí počet znaků ve smyslu opravdových znaků, ale ve smyslu počtu prvků typu char.
Teď vidím, že to surrogate pair není a že to jsou opravdu jen 2 písmena S - s takovou věcí jsem se ještě nesetkal, každopádně není dobré se spoléhat na String.length, pokud chci počet znaků.
Věřím v jednoho Boha.
28.8.2010 21:06 Martin Mareš
Rozbalit Rozbalit vše Re: Programátorská hádanka 4 - céčkovská zrada
On by si předně každý, kdo chce měřit délku unicodových řetězců, měl opravdu pořádně rozmyslet, co vlastně chce:
  • počet jednotek reprezentace (v UTF-8 nebo UTF-16)
  • počet codepointů
  • počet znaků (liší se v případě použití kombinujících znaků)

Založit nové vláknoNahoru

ISSN 1214-1267   www.czech-server.cz
© 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.