Eida.cz - Ach, ty projekty

Ach, ty projekty

Eida

Prej nic nedělám. Hm. Sám bych to neřekl. Je totiž pozdě, takže jedu naplno. Není to tak dávno, co jsem se vrátil zpátky do školy a myslím si, že mi to i jde. Teda zatím. Byl jsem tam totiž teprv jen jednou...

Jak už jsem psal někde minule, trochu mě překvapilo, co tam teď chodí za namyšlené trubky. Myslím, že po prvních dvou týdnech někteří z nich pochopili, že se musí snažit sami, jinak jdou do oleje, alespoň podle jednoho fóra. Ti, co ještě ne, by se měli zamyslet a připravit se na oheň pekelný, neboť nikdo za ně nemůže dělat jejich práci. Pochopí časem :). 

Ale to je vedlejší. Co je zábavnější, kdo všechno už má hotové projekty? A tím nemyslím uznané body, že. Poslední změna zadání prvního projektu byla 18. září, semestr začal 21. září, první povídání bylo 22. září. Dneska je 30. září a nevšiml jsem si, že by hotových projektů bylo tolik. Mně chybí už jen poladit čtyřku.

Problémy jsou tady zhruba dva. Tím prvním je pravděpodobně obecná neznalost jazyka C, druhým, ale o mnoho závažnějším, neschopnost vrstveného myšlení. C je sám o sobě celkem snadný jazyk a neměl by být problém se naučit ho na základní úrovni ovládat během jednoho dne. Uznávám, že to může být náročné pro někoho, kdo ve škole nikdy neviděl ani Pascal, ale je to boj - jak bylo řečeno minule, když už se někdo přihlásí na tohle studium, měl by se sám zajímat.

O dost náročnější je jak definice, tak případné řešení druhého problému. Vůbec největším problémem může často být kompletní nebo částečné nepochopení samotného zadání. Ono naučit se myslet není záležitost jednoho dne, ale existuje dostatek způsobů, jak to celé urychlit. Celkem dobrým začátkem by mohl být rozbor nějaké reálné analogie, sepsání dejme tomu pracovního postupu (třeba stavbu krmítka pro ptáky), zpětné vytvoření osnovy a vymezení klíčových částí a nakonec zpracování jednoduchého vývojového diagramu. Vývojové diagramy jsou vůbec vhodné téměř na cokoliv. 

Po technické stránce je vhodé rovnou začít v UNIXu, programování ve Windows moc nemá cenu. Všechno tam (ne)funguje poněkud jinak a občas se člověk ani nestačí divit. Možná mám moc velkou slabost pro BSD :), ale jednodušší a dostatečný je na to samozřejmě Linux.

Ale aby to nebylo jen zbytečné plkání do tmy, podíváme se trochu konkrétněji na první reálný projekt. 

Zadání

Cílem je vytvoření programu pro jednoduché zpracování textu ovládaného z příkazové řádky. Program přečtě text ze standardního vstupu a podle uvedených parametrú ho upravený vypíše na standardní výstup. Vstupní text má být tvořen slovy a větami, cokoliv může být odděleno libovolným počtem bílých znaků. Výstup má obsahovat slova oddělená pouze jedinou mezerou a celý výstup má být ukončen jedním koncem řádku (\n) a na začátku ani na konci textu nesmí být nikdy mezera. Věty mají být ukončeny tečkou. Bude-li věta ukončena více neoddělenými tečkami, za konec věty bude považována pouze poslední tečka. Budou-li tečky odděleny, budou považovány za jednotlivé prázdné věty (program neuvažuje zkratky ukončené tečkami). Vstupní parametry z příkazového řádku se musí vejít do unsigned long int. Bude-li vstup mimo rozsah, měl by program vypsat chybu. Pro čtení, resp. výpis smí být použity pouze funkce getchar(), getc() resp. putchar(), putc()

No co k tomu dodat. Bude se tedy jednat o konzolovou aplikaci pouštěnou z příkazové řádky s parametry. Po správném zadání parametrů program bude čekat na vstup z klávesnice až do ukončení (CTRL+D v UNIXu, nebo CTRL+Z na Windows). Poté vypíše očekávaný výsledek. Standardní vstup a výstup jsou popisovače souborů, více viz man stdin, man stdout. A pro načítání a výpis smí být použity pouze výše uvedené funkce, čili žádné printf() a podobně.

Teoretická východiska

Prvním krokem by teď měla být dekompozice celého problému na vícero drobných částí. Umění správně dekomponovat problém je jedním z nejdůležitějších faktorů a znatelně ovlivňuje čas potřebný na práci. V našem konkrétním příkladě bych to viděl asi následovně:

  • Rozparsování a analýza argumentů získaných z příkazové řádky
  • Načtení vstupního řetězce
  • Odstranění všech zbytečných bílých znaků v řetězci
  • Úprava řetězce podle zadaných parametrů
  • Výpis a uvolnění zdrojů z paměti, ukončení

Implementace

Pro práci s argumenty je vhodné použít strukturu obsahující jednotlivé statické parametry (v tomto případě pouze N), stavový kód pro případné vypsání chyby a případně pro zjednodušení ukazatel na dále použitou funkci (zpracování jako wpl nebo spl :)). Ze zadání vyplývá kontrola mezí vloženého N. Způsobů kontroly může být několik a je na každém, jak chytré řešení zvolí.

Načtení řetězce ze standardního vstupu se dá vyřešit využitím poskytnuté ukázkové funkce readline(), ovšem je více než vhodné provést jisté drobné úpravy.

Klíčovým je odstranění všech bílých znaků ze vstupu a jejich nahrazení jednoduchými mezerami, tedy jakýsi trim. Vývojový diagram tohoto kroku se krásně vejde na stránku A5 a je překvapivě jednoduchý na to, jak ošklivě to zní. 

flowchart - izpTrim, projekt 1

Ze zadaných parametrů už víme, kterou funkci použijeme. Pro wpl budeme nahrazovat každou (N-1)-tou mezeru novým řádkem, pro spl budeme vkládat nový řádek za každou N-tou větnou tečku (viz více teček v jedné větě).

Poté řetězec výhradně pomocí povolených funkcí vypíšeme na standardní výstup a přidáme nový řádek. Všechny alokované zdroje uvolníme. Na odhalení leaků a zapomentých uvolnění paměti je v Linuxu vhodný program valgrind

A violá, máme hotovo. Díky správnému použití standardního vstupu a výstupu je program schopen přesměrovávání a používání přes rouru, což je velice výhodné.

Metriky kódu (pro představu)

V mém případě to dopadlo takto:

Velikost kódu (s mnoha komentáři): 9 716 B UNIX, ISO-8859-2
Počet řádků i s komentáři: 478  
Velikost spustitelného programu: 21 812 B

32bit PowerPC, Darwin 8.11


 
9 905 B

32bit x86, Linux 2.6

Vývoj netrval nikterak dlouho... akorát tenhle článek píšu dva dny :D. Jak už bylo řečeno, hlavní a nejdůležitější je umět správně rozložit zadaný problém a přesně skládat část po části do jednoho kouzelného celku. Tak tedy hodně štěstí, je to přece jednoduché. :)

Tento článek přečetlo již 874 čtenářů (0 dnes).

Komentáře

Nový komentář