abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 13:33 | Nová verze

    Vyšlo Pharo 12.0, programovací jazyk a vývojové prostředí s řadou pokročilých vlastností. Krom tradiční nadílky oprav přináší nový systém správy ladících bodů, nový způsob definice tříd, prostor pro objekty, které nemusí procházet GC a mnoho dalšího.

    Pavel Křivánek | Komentářů: 2
    dnes 04:55 | Zajímavý software

    Microsoft zveřejnil na GitHubu zdrojové kódy MS-DOSu 4.0 pod licencí MIT. Ve stejném repozitáři se nacházejí i před lety zveřejněné zdrojové k kódy MS-DOSu 1.25 a 2.0.

    Ladislav Hagara | Komentářů: 22
    včera 17:33 | Nová verze

    Canonical vydal (email, blog, YouTube) Ubuntu 24.04 LTS Noble Numbat. Přehled novinek v poznámkách k vydání a také příspěvcích na blogu: novinky v desktopu a novinky v bezpečnosti. Vydány byly také oficiální deriváty Edubuntu, Kubuntu, Lubuntu, Ubuntu Budgie, Ubuntu Cinnamon, Ubuntu Kylin, Ubuntu MATE, Ubuntu Studio, Ubuntu Unity a Xubuntu. Jedná se o 10. LTS verzi.

    Ladislav Hagara | Komentářů: 13
    včera 14:22 | Komunita

    Na YouTube je k dispozici videozáznam z včerejšího Czech Open Source Policy Forum 2024.

    Ladislav Hagara | Komentářů: 2
    včera 13:22 | Nová verze

    Fossil (Wikipedie) byl vydán ve verzi 2.24. Jedná se o distribuovaný systém správy verzí propojený se správou chyb, wiki stránek a blogů s integrovaným webovým rozhraním. Vše běží z jednoho jediného spustitelného souboru a uloženo je v SQLite databázi.

    Ladislav Hagara | Komentářů: 0
    včera 12:44 | Nová verze

    Byla vydána nová stabilní verze 6.7 webového prohlížeče Vivaldi (Wikipedie). Postavena je na Chromiu 124. Přehled novinek i s náhledy v příspěvku na blogu. Vypíchnout lze Spořič paměti (Memory Saver) automaticky hibernující karty, které nebyly nějakou dobu používány nebo vylepšené Odběry (Feed Reader).

    Ladislav Hagara | Komentářů: 0
    včera 04:55 | Nová verze

    OpenJS Foundation, oficiální projekt konsorcia Linux Foundation, oznámila vydání verze 22 otevřeného multiplatformního prostředí pro vývoj a běh síťových aplikací napsaných v JavaScriptu Node.js (Wikipedie). V říjnu se verze 22 stane novou aktivní LTS verzí. Podpora je plánována do dubna 2027.

    Ladislav Hagara | Komentářů: 0
    včera 04:22 | Nová verze

    Byla vydána verze 8.2 open source virtualizační platformy Proxmox VE (Proxmox Virtual Environment, Wikipedie) založené na Debianu. Přehled novinek v poznámkách k vydání a v informačním videu. Zdůrazněn je průvodce migrací hostů z VMware ESXi do Proxmoxu.

    Ladislav Hagara | Komentářů: 0
    včera 04:11 | Nová verze

    R (Wikipedie), programovací jazyk a prostředí určené pro statistickou analýzu dat a jejich grafické zobrazení, bylo vydáno ve verzi 4.4.0. Její kódové jméno je Puppy Cup.

    Ladislav Hagara | Komentářů: 0
    24.4. 22:44 | IT novinky

    IBM kupuje společnost HashiCorp (Terraform, Packer, Vault, Boundary, Consul, Nomad, Waypoint, Vagrant, …) za 6,4 miliardy dolarů, tj. 35 dolarů za akcii.

    Ladislav Hagara | Komentářů: 16
    KDE Plasma 6
     (73%)
     (9%)
     (2%)
     (16%)
    Celkem 790 hlasů
     Komentářů: 4, poslední 6.4. 15:51
    Rozcestník

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

    26.8.2010 19:00 | Přečteno: 1813× | 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
    We will destroys the Christian's legion ... and the cross, will be inverted
    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.
    We will destroys the Christian's legion ... and the cross, will be inverted
    Aleš Janda avatar 26.8.2010 20:17 Aleš Janda | skóre: 23 | blog: kýblův blog | Praha
    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: 45 | 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: 23 | blog: kýblův blog | Praha
    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: 45 | 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: 9 | 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: 23 | blog: kýblův blog | Praha
    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: 23 | blog: kýblův blog | Praha
    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: 23 | blog: kýblův blog | Praha
    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: 23 | blog: kýblův blog | Praha
    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: 23 | blog: kýblův blog | Praha
    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: 23 | blog: kýblův blog | Praha
    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: 68 | 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: 23 | blog: kýblův blog | Praha
    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: 72 | 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: 23 | blog: kýblův blog | Praha
    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: 62 | 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: 62 | 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.