Zadanie 3

Zadanie 3

Nezabudnite zadanie nahrať do AIS do príslušného miesta odovzdania (odovzdajte len jeden zdrojový .c súbor).

Dôležité informácie

  • Termín odovzdania: Odovzdajte do AIS, 12. apríl 2020, 23:59
  • Počet bodov: 10
  • Odovzdaný súbor musí byť pomenovaný vo formáte ID.z3.c (ID nahraďte vašim AIS ID číslom).
  • Podmienkou získania bodov za zadanie je, aby bol váš kód kompilovateľným prekladačom gcc s prepínačom -Wall bez chýb a upozornení (teda 0 errors, 0 warnings). Na otestovanie tejto nutnej podmienky máte rôzne možnosti:
    • použite Linux, nainštalujte si prostredie Cygwin alebo ľuboveľné IDE prepojené s MinGW a tam pomocou gcc skompilujte svoj kód, príkaz na kompiláciu je:
      gcc -Wall zdrojak.c -o my_program

      Skompiluje zdrojový súbor s názvom zdrojak.c a výstupný spustiteľný program pomenuje ako my_program, návod na základné použitie gcc.

    • otestujte váš kód online na webstránke rextester.com, kde je nutné pred kompiláciou začiarknuť možnosť Show compiler warnings
    • otestujte váš kód na stránke OnlineGDB ... v nastaveniach v sekcii Extra Compiler Flags si viete zadať prepínač -Wall
  • Nezabudnite dodržať termín odovzdania do AIS, oneskorené odovzdanie nebude akceptované.

Obsah


Príprava

Ešte predtým ako začnete pracovať na zadaní, krátka sumarizácia:

Cieľ zadania

Naprogramujte v jazyku C terminálový textový procesor, ktorý bude spracovávať riadky textu a jeho správanie bude riadené prepínačmi z príkazového riadku terminálu (CMD argumenty).

Vstupný text bude program získavať zo štandardného vstupu, t.j. priamo z klávesnice alebo pomocou presmerovania štandardného vstupu z textového súboru. Program spracuje vstupný text po riadkoch so stanovenou maximálnou dĺžkou riadku (ak je dlhší, zvyšok sa spracuje ako nový riadok). Po načítaní sa na riadok aplikuje vstupná transformácia, t.j. riadok sa spracuje podľa vstupných prepínačov. Následne sa na takto spracovaný riadok aplikuje výstupná transformácia, t.j. riadok sa spracuje podľa výstupných prepínačov. Riadok sa po výstupnej transformácii vypíše do terminálu. Program nesmie vypisovať nič iné len výsledok spracovania riadku.

Toto zadanie je zamerané predovšetkým na prácu s CMD argumentami, znaky a reťazce (viď odkazy hore na aktuálne prednášky).

Hlavné body zadania

  • Napísať hlavnú spúšťaciu funkciu run_text_processor(...), ktorá vykoná nasledovné úkony:
    1. Spracuje platné prepínače zadané vo forme CMD argumentov (pomocou vlastnej samostatnej funkcie) a výsledok spracovania si uloží do vhodných premenných, ktoré sa neskôr použijú pri spracovávaní riadkov textu.
    2. Načítava text po riadkoch a pre každý riadok (v danom poradí):
      • vykoná vstupné spracovanie pomocou operácie určenej vstupnými prepínačmi (spracovanie zabezpečí príslušná vlastná funkcia) POZOR: vstupné transformácie sa vykonajú v takom poradí v akom boli zadané pri spustení programu
      • vykoná výstupné spracovanie, t.j. výsledok predchádzajúceho kroku sformátuje podľa výstupných prepínačov (zabezpečí to príslušná vlastná funkcia) POZOR: výstupné transformácie sa vykonajú v takom poradí v akom boli zadané pri spustení programu
      • po výstupnom spracovaní sa riadok vypíše do terminálu
  • Napísať funkciu na spracovanie CMD argumentov, ktorá rozpozná vstupno/výstupné prepínače a uloží potrebné nastavenia do premenných. Na rozpoznanie CMD argumentov odporúčam použiť funkciu getopt, ktorá vám zjednoduší prácu (viac o tejto téme nižšie).
  • Napísať jednotlivé funkcie na vstupné spracovanie riadku (každý vstupný prepínač určuje iný spôsob spracovania riadku textu a preto by mala byť pre každý vstupný prepínač napísaná samostatná funkcia).
  • Napísať jednotlivé funkcie na výstupné spracovanie riadku, t.j. sformátovanie výsledku vstupného spracovania textu (každý výstupný prepínač určuje iný spôsob sformátovania reťazca a preto by mala byť pre každý výstupný prepínač napísaná samostatná funkcia).

Ukážka (video)

V týchto video ukážkach vidíte rôzne možnosti spustenia programu (rôzne prepínače, vstupné texty). Urobte si rovnaké experimenty a overte si správnosť vášho riešenia. Samozrejme, ak vám to bude fungovať podľa ukážky neznamená to, že vaše riešenie je 100 % správne, testovať treba rozsiahlejšie. Váš program musí fungovať s rôznymi kombináciami prepínačov a vstupných textov.

Ďalšie video ukážky budem postupne pridávať....

  • Ukážka 1: Ukážka spustenia programu z terminálu, pričom vstupný text je raz zadaný z klávesnice a raz pomocou presmerovania štadardného vstupu.

Postup

1. Spracovanie CMD argumentov

1.1 Parametre argc a argv

Ako prvé si naštudujte problematiku spracovania CMD argumentov v jazyku C. Program môže byť v termináli spustený s použitím prídavných argumentov, ktoré v príkazovom riadku nasledujú po názve programu. Tieto argumenty môžu byť čísla alebo ľubovoľný text, avšak v C sú vždy reprezentované ako reťazce (t.j. aj číslo je chápané ako reťazec). Navyše ak chcete, aby bol dlhší text obsahujúci medzery chápaný ako jeden argument, treba daný text uzatvoriť do úvodzoviek (viď príklad).

./my_program 1 2 tri styri "toto je jeden argument"

Tento zápis predstavuje spustenie programu my_program v Linux termináli spolu prisluchajúcimi argumentami (dokopy 6 argumentov, vrátane názvu programu).

Hlavná main funkcia vie tieto CMD argumenty preniesť do vášho programu pomocou jej parametrov:

  • argc - je číslo, ktoré predstavuje počet CMD argumentov vrátane názvu programu (t.j. pre náš príklad je to 6)
  • argv - je to pole všetkých CMD argumentov programu, kde je každý argument reprezentovaný ako C reťazec (z technického hľadiska sa jedná o pole obsahujúce smerníky na začiatok jednotlivých reťazcov uložených v pamäti)
int main(int argc, char* argv[]) 
{ 
    /*
        argc - pocet CMD argumentov (vratane nazvu programu)
        argv - pole argumentov
    */
    return 0; 
} 

Viac o argc a argv sa dočítate na tutorialspoint.com.

Mini úloha: Napíšte si C program, ktorý prejde celé pole argv a vypíše všetky zadané CMD argumenty. Skúste program spustiť v termináli a nezadať mu žiadny argument resp. zadať mu viacero argumentov napr. podľa príkladu hore.

1.2 Funkcia getopt

V tomto zadaní budeme pracovať s prepínačmi (t.j. CMD argument v tvare -x, kde x je ľubovoľné písmeno), ktoré budú určovať, čo program vykoná. Spracovanie a odhalenie platných prepínačov výrazne zjednoduší funkcia getopt. Na úvod si prečítajte tieto zdroje, ktoré popisujú funkciu getopt spolu s príkladmi jej použitia:

int getopt(int argc, char* const argv[], const char* optstring);

Funkcia getopt spracúva CMD argumenty. Funkcia má 3 parametre. Prvé dva parametre argc (počet CMD argumentov) a argv (pole CMD argumentov) sú rovnaké ako parametre, ktoré vstupujú do funkcie main. Tretí parameter optstring je reťazec obsahujúci platné znaky prepínačov. Funkcia getopt funguje tak, že spracúva pole argv a pri každom jej zavolaní vráti znak prepínača. Ak narazí na neznámy prepínač, vráti znak '?'. Ak prepínač vyžaduje zadanie hodnoty (napr. -e 4), musíme do reťazca optstring za znakom konkrétneho prepínača uviesť symbol :. Hodnota prepínača je uložená do globálnej premennej optarg (viď zdroje). Keď funkcia getopt už nenájde žiadny prepínač, vráti -1. Presné fungovanie funkcie getopt si treba samostatne naštudovať.

Funkciu getopt môžete použiť na Unix-like systémoch a na jej použitie potrebujete vložiť do programu hlavičkový súbor unistd.h. Ak pracujete vo Visual Studio, nie je možné ju využiť. Aby ste mohli vo Windows pracovať s funkciou getopt, nainštalujte si prostredie MinGW (obsahuje Unix-like programovacie nástroje ako gcc, make a pod.). Následne na programovanie použite niektoré z týchto vývojových prostredí:

  • CLion (treba ho nakonfigurovať tak, aby použil nainštalované MinGW)[získanie študentskej licencie]
  • Code::Blocks (dá sa stiahnuť so zabudovaným MinGW alebo samostatne, vtedy ho treba nakonfigurovať tak, aby použil externé MinGW)
  • alebo použite Dev-C++ (už obsahuje zabudované MinGW)

2. Čítanie riadkov zo štandardného vstupu

Po spustení začne program v cykle čítať riadky textu. Na čítanie riadkov textu použite funkciu fgets (poriadne si ju naštudujte). Maximálna dĺžka načítaného riadku je 80. Riadok sa uloží do reťazca, ktorý má dostatočnú kapacitu. Kapacitu reťazca si zámerne zvoľte tak, aby bola oveľa väčšia ako maximálna dĺžka riadku, pretože po spracovaní sa môže riadok predĺžiť (alebo ak viete, môžete používať dynamicky alokované pole). Nezabudnite, že po načítaní riadku je tento ukončený znakom \n, ktorý sa nebude spracovávať. Ak používateľ zadá v termináli dlhší riadok ako je maximálna povolená dĺžka, v tom prípade sa zvyšná časť spracuje ako nový riadok v ďalšej iterácii cyklu. Program dokončí čítanie riadkov keď dostane na vstupe prázdny riadok, t.j. reťazec obsahujúci len \n.

Pri testovaní vášho programu môžete v termináli presmerovať štandardný vstup tak, aby získaval vstupné riadky z textového súboru.

3. Vstupné prepínače

Program musí vedieť pracovať s týmito vstupnými prepínačmi:

3.1 Prepínač -u

Všetky písmená v riadku sa prekonvertujú na veľké (použite funkciu toupper).

(Príklad 1) Program spustíme v termináli príkazom: ./my_program -u.

Vstupný text (prvý riadok) a výsledok spracovania (druhý riadok) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABC ABC 1C2I3S4L5O ??? ..W...W..     DLHYABCTEXT---[JAZYK C]

3.2 Prepínač -l

Všetky písmená v riadku sa prekonvertujú na malé (použite funkciu tolower).

(Príklad 1) Program spustíme v termináli príkazom: ./my_program -l.

Vstupný text (prvý riadok) a výsledok spracovania (druhý riadok) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
abc abc 1c2i3s4l5o ??? ..w...w..     dlhyabctext---[jazyk c]

3.3 Prepínač -a

Iné znaky ako písmená sa nahradia 1 medzerou (ak vzniknú duplicitné medzery, spoja sa do jednej) ... použite funkciu isalpha.

(Príklad 1) Program spustíme v termináli príkazom: ./my_program -a.

Vstupný text (prvý riadok) a výsledok spracovania (druhý riadok) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABC abc c i s l o w W dlhyabctext jazyk C 

3.4 Prepínač -c

Všetky písmená riadku sa presunú na jeho začiatok (ostatné znaky sú vynechané), medzi písmenami nebudú medzery.

(Príklad 1) Program spustíme v termináli príkazom: ./my_program -c.

Vstupný text (prvý riadok) a výsledok spracovania (druhý riadok) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABCabccislowWdlhyabctextjazykC

3.5 Prepínač -r PARAM

Tento prepínač vyžaduje povinný parameter PARAM. Ak zadáme tento prepínač, tak sa v riadku nahradia všetky výskyty reťazca PARAM príslušným počtom * (operácia je case-sensitive). Funkcia nahradí len neprekrývajúce sa reťazce. Na vyriešenie tejto úlohy odporúčam použiť funkciu strstr.

(Príklad 1) Program spustíme v termináli príkazom: ./my_program -r abc.

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABC *** 1c2i3s4l5o ??? ..w...W..     dlhy***text---[jazyk C]

(Príklad 2) Program spustíme v termináli príkazom: ./my_program -r 1..2..1.

(:?_) 1..2..1..2..1..2..1......1..2..1....2.1 abc 121
(:?_) *******..2..*******......*******....2.1 abc 121

(Príklad 3) Program spustíme v termináli príkazom: ./my_program -r "oj a".

Ahoj ako sa mas? Vojak. AHoj ako--ahOj ako--stoj alebo bez, stroj   abc. 
Ah****ko sa mas? Vojak. AH****ko--ahOj ako--st****lebo bez, stroj   abc.

3.6 Prepínač -e PARAM

Zašifruje len písmená riadku pomocou Cézarovej šifry (t.j. písmeno sa posunie o určitých počet pozícií v abecede dopredu(+) alebo dozadu(-)). Povinný parameter prepínača PARAM určuje posun v abecede (môže byť kladný aj záporný posun v abecede).

Nápoveda: Pri šifrovaní je dobré si napísať vlastnú funkciu int cezar_posun(int c, int k), ktorá posunie vstupné pismeno c (jeho ASCII kód) o k pozícií. Takto zašifrované písmeno funkcia vráti.

Algoritmus šifrovania písmena:

  1. Skonvertujte vstupné písmeno c na číslo v rozsahu <0,25>.
  2. Použite sčítanie c+k modulo 26: pozor na záporné čísla, otestujte si to.
  3. Výsledok skonvertujte naspäť na príslušný ASCII kód.

    (Príklad 1) Program spustíme v termináli príkazom: ./my_program -e 2.

    ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
    CDE cde 1e2k3u4n5q ??? ..y...Y..     fnjacdevgzv---[lcbam E]

    (Príklad 2) Program spustíme v termináli príkazom: ./my_program -e -3.

    ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
    XYZ xyz 1z2f3p4i5l ??? ..t...T..     aievxyzqbuq---[gxwvh Z]

3.7 Ukážky: kombinácie vstupných prepínačov

Ak program spustíme s kombináciou viacerých vstupných prepínačov, na riadok textu sa aplikujú transformácie v poradí podľa prepínačov. Pripájam zopár vysvetľujúcich ukážok kombinácie vstupných prepínačov. Program musí fungovať s ľubovoľnou kombináciou vstupných prepínačov. Viacnásobné použitie toho istého prepínača neuvažujeme.

  • Príkaz: ./my_program -u -c.

    ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
    ABCABCCISLOWWDLHYABCTEXTJAZYKC
  • Príkaz: ./my_program -l -r abc.

    ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
    *** *** 1c2i3s4l5o ??? ..w...w..     dlhy***text---[jazyk c]
  • Príkaz: ./my_program -u -r A -e 1.

    ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
    *CD *CD 1D2J3T4M5P ??? ..X...X..     EMIZ*CDUFYU---[K*AZL D]
  • Príkaz: ./my_program -u -e 1 -r A.

    ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
    BCD BCD 1D2J3T4M5P ??? ..X...X..     EMIZBCDUFYU---[KB*ZL D]

4. Výstupné prepínače

Potom ako sa na riadok aplikujú všetky vstupné transformácie podľa všetkých vstupných prepínačov, riadok bude spracovaný výstupnými transformáciami - tie sú určené tentokrát výstupnými prepínačmi.

Program musí vedieť pracovať s týmito výstupnými prepínačmi:

4.1 Prepínač -w

Každé slovo sa vypíše na samostatný riadok (slovo je v tomto kontexte chápané ako postupnosť alfanumerických znakov, oddelené inými znakmi). Nealfanumerické znaky sa nevypíšu. Overenie, či je znak alfanumerický sa dá urobiť pomocou funkcie isalnum. Rozdelenie reťazca na podreťazce (slová) pomocou zvolených oddeľovačov sa dá urobiť pomocou funkcie strtok.

(Príklad 1) Program spustíme v termináli príkazom: ./my_program -w.

Vstupný text (prvý riadok) a výsledok spracovania (zvyšné riadky) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABC
abc
1c2i3s4l5o
w
W
dlhyabctext
jazyk
C

4.2 Prepínač -g PARAM

Použije sa iba ak bol použitý prepínač -c (po použití prepínača -c nezostanú v riadku žiadne medzery). Rozdelí riadok do skupín znakov dĺžky danej povinným parametrom PARAM. Skupiny znakov budú oddelené jednou medzerou. PARAM nesmie byť záporný.

(Príklad 1) Program spustíme v termináli príkazom: ./my_program -c -g 3.

Vstupný text (prvý riadok) a výsledok spracovania (zvyšné riadky) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABC abc cis low Wdl hya bct ext jaz ykC

(Príklad 2) Program spustíme v termináli príkazom: ./my_program -g 7 -u -c.

Vstupný text (prvý riadok) a výsledok spracovania (zvyšné riadky) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABCABCC ISLOWWD LHYABCT EXTJAZY KC

4.3 Ukážky: kombinácie vstupných a výstupných prepínačov

Vstupné a výstupné prepínače je môžné rôzne kombinovať. Uvádzam niektoré príklady.

(Príklad 1) Príkaz: ./my_program -a -w.

Vstupný text (prvý riadok) a výsledok spracovania (zvyšné riadky) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
ABC
abc
c
i
s
l
o
w
W
dlhyabctext
jazyk
C

(Príklad 2) Príkaz: ./my_program -l -c -g 5 -w.

Vstupný text (prvý riadok) a výsledok spracovania (zvyšné riadky) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
abcab
ccisl
owwdl
hyabc
textj
azykc

(Príklad 3) Príkaz: ./my_program -e 4 -c -g 2.

Vstupný text (prvý riadok) a výsledok spracovania (zvyšné riadky) bude vyzerať nasledovne:

ABC abc 1c2i3s4l5o ??? ..w...W..     dlhyabctext---[jazyk C]
EF Ge fg gm wp sa Ah pl ce fg xi bx ne dc oG

5. Ukončenie programu

Program skončí:

  • keď dostane na vstupe prázdny riadok, t.j. riadok obsahujúci len znak \n
  • keď dostane z príkazového riadku neplatný prepínač, napr. ./program -c -s, kde s je neplatný prepínač (program skončí bez výpisu na štandardný výstup)
  • keď nie je zadaný povinný parameter PARAM prepínača alebo je tento parameter v nesprávnom tvare, napr. ./program -g, kde chýba povinný parameter za prepínačom -g (program skončí bez výpisu na štandardný výstup)

Kostra riešenia

Toto je kostra riešenia, ktorá slúži ako inšpirácia/pomôcka/návod v hrubých rysoch. Nezabudnite, že sa hodnotí kvalita vášho programátorského návrhu. Rozdeľte celý program do vhodných funkcií. Vyvarujte sa na maximum používaniu globálnych premenných a nebezpečným programátorským konštrukciám.

#include <stdio.h>
#include <stdlib.h>
#include <ctype.h> // praca so znakmi
#include <string.h> // praca s retazcami
#include <unistd.h> // funkcia getopt()

/* ----------- POZNAMKY ------------ */

// Vstupne prepinace:
// -u
// -l
// -a
// -c
// -r PARAM
// -e PARAM

// Vystupne prepinace:
// -w
// -g PARAM

/* --------------------------------- */

// FUNKCIE PRE VSTUPNE/VYSTUPNE SPRACOVANIE

// ... Na tomto mieste si napiste implementacie
// ... vsetkych funkcii pre jednotlive vstupne aj
// ... vystupne prepinace. Tieto funkcie budu
// ... spracovavat riadok textu.

// ... Kazda funkcia na spracovanie riadku moze mat
// ... nasledujuci prototyp (vid nizsie). Cize
// ... vstupom bude smernik na vstupny riadok
// ... textu a funkcia ho vo svojom tele spracuje.

// void fun_process_line(char line[]);

// ********** FUNKCIE PRE VSTUPNE PREPINACE **********

// funkcia pre prepinac -l
// TODO

// funkcia pre prepinac -u
// TODO

// funkcia pre prepinac -a
// TODO

// funkcia pre prepinac -c
// TODO

// funkcia pre prepinac -r PARAM
// TODO

// funkcia pre prepinac -e PARAM
// TODO

// ********** FUNKCIE PRE VYSTUPNE PREPINACE **********

// funkcia pre prepinac -w
// TODO

// funkcia pre prepinac -g PARAM
// TODO

// MIESTO PRE DALSIE FUNKCIE

// ... Je idealne mat samostatnu funkciu
// ... na spracovanie CMD argumentov, ktora
// ... precita vsetky platne prepinace a pripravi
// ... vas program na spravne spracovanie textu
// ... t.j. nastavi sa spravne poradie vstupnych
// ... transformacii a nasledne spravne poradie
// ... vystupnych transformacii.

// HINT:
// ... Mozete si napisat zvlast funkciu, ktora precita
// ... len vstupne prepinace, ulozi si ich poradie
// ... napriklad do pola a podla toho vykona
// ... spracovanie riadku. To iste bude platit pre
// ... vystupne prepinace.

// ... Tymto sposobom sa vyhnete problemom pri
// ... "premiesani" vstupnych a vystupnych prepinacov
// ... a odseparujete ich. Prepinace sa mozu zadavat
// ... v lubovolnom poradi.

// Hlavna spustacia funkcia, ktora vykona postupnost
// krokov na spracovanie riadkov textu.
// Vstupmi su zname parametre 'argc' a 'argv'.
void run_text_processor(int argc, char *argv[]) {

    // TODO
    // 1. Spracuju sa CMD argumenty a ulozia sa potrebne nastavenia.

    // 2. V cykle sa nacitavaju riadky a nasledne sa spracuvaju.
    //
    //    2.1 Nacita sa riadok (riadok je ukonceny znakom '\n',
    //        ten sa vsak v programe nespracovava).
    //    2.2 Vykona sa seria vstupnych transformacii podla
    //        vstupnych prepinacov.
    //    2.3 Vykona sa seria vystupnych transformacii podla
    //        vystupnych prepinacov.
    //    2.4 Vysledny spracovany riadok sa vypise do terminalu

}

int main(int argc, char *argv[]) {
    run_text_processor(argc, argv);
    return 0;
}

Poznámka: Pokročilejší programátori môžu pri riešení tohto zadania využiť aj smerníky na funkciu (z angl. function pointers), čo výrazne zjednoduší implementáciu. Konkrétne, môžete využiť pole smerníkov na funkcie na zaznamenanie postupnosti operácií, ktoré sa majú vykonať s načítaným riadkom textu. Napr. si vytvoríte zvlášť pole pre vstupné transformácie a tam uložíte smerníky na funkcie, ktoré vykonávajú jednotlivé operácie podľa poradia vstupných prepínačov. To isté môžete urobiť aj pre výstupné transformácie. Následne, keď budete mať prečítané všetky CMD argumenty a naplnené polia so smerníkmi na vstupné aj výstupné funkcie, potom stačí už len v cykle prejsť jednotlivé polia a vždy zavolať funkciu, ktorej adresa je umiestnená na príslušnom indexe poľa.

Príklad poľa smerníkov na funkcie:

#include <stdio.h>

int sum(int a, int b){
    return a+b;
}

int mul(int a, int b){
    return a*b;
}

// typedef: pomenovanie noveho typu
// pointer na funkciu, ktora vracia int
// a na vstupe ocakava dva parametre
// typu int

typedef int (*fn)(int,int);

int main()
{
    // pole smernikov na funkcie
    fn arr[2]; 
    arr[0] = sum; // ukladame adresu funkcie na scitanie 
    arr[1] = mul; // ukladame adresu funkcie na nasobenie

    // postupne volanie funkcii z pola
    int i, r;
    for(i = 0; i < 2; i++){
        r = arr[i](i+1,i+2); // volanie funkcie
        printf("%d\n", r);
    }
    return 0;
}

Testovací dataset

Aby ste si mohli overiť správne fungovanie vášho programu, pripájam testovací dataset (TXT súbor), ktorý obsahuje rôzne (prázdnym riadkom oddelené) kombinácie prepínačov a vstupných textov a k nim priradený správny výsledok spracovania textu, ktorý by mal váš program vypísať. V datasete nie je žiadny vstupný text dlhší ako spomínaný limit 80 znakov.

Dataset pozostáva z testovacích vzoriek oddelených prázdnymi riadkami, pričom jedna testovacia vzorka má nasledovnú štruktúru:

  • riadok s použitými prepínačmi (presne v danom poradí sa budú testovať)
  • riadok so vstupným textom (tento text váš program spracuje)
  • výstupné riadky (predstavujú konečný výsledok spracovania vstupného textu)

Náhľad datasetu:

-u -c -e 6
Toto je prvy testovaci text ... 123456 [koniec]
ZUZUPKVXBEZKYZUBGIOZKDZQUTOKI

-l -a -r to -w
Toto je druhy testovaci text ... 123456 [koniec]
je
druhy
tes
vaci
text
koniec

-c -g 4
Toto je treti testovaci text ... 123456 [koniec]
Toto jetr etit esto vaci text koni ec

-r "a b a" -e 1
A a b a b a b a B a B a       a b a
B ***** c ***** C b C b       *****

Testovanie/bodovanie bude samozrejme prebiehať na odlišnom neverejnom datasete. Tento dataset slúži len kontrolu rôznych scenárov spustenia a ak sa vaše výsledky zhodujú, je vysoká šanca, že vaše riešenie bude fungovať aj na ostrom datasete.

Bodovanie

Zadanie bude hodnotené pomocou automatizovaných testov (otestuje sa séria rôznych prepínačov a vstupných textov) a preto je potrebné, aby váš program vypisoval na štandardný výstup len výsledok spracovania riadkov (podľa zadania) - žiadne iné znaky. Ak túto podmienku váš program nesplní, je dosť možné, že za zadanie nezískate žiadne body. Preto výrazne odporúčam využiť testovací dataset a vaše výsledky porovnať so správnymi (musia sa zhodovať všetky znaky).

Body sú orientačne rozdelené nasledovne (body budú prepočítané tak, aby max. bolo 10 získaných bodov):

  • [1b] Za správne fungovanie vstupných prepínačov. Program bude testovaný tak, že bude spustený vždy len s jedným vstupným prepínačom.
  • [1,5b] Za správne fungovanie kombinácie vstupných prepínačov. Program bude testovaný tak, že bude spustený vždy s rôznymi kombináciami vstupných prepínačov. Viacnásobné použitie rovnakého prepínača nebude testované.
  • [1b] Za správne fungovanie výstupných prepínačov. Program bude testovaný tak, že bude spustený vždy len s jedným výstupným prepínačom.
  • [1,5b] Za správne fungovanie kombinácie výstupných prepínačov. Program bude testovaný tak, že bude spustený vždy s rôznymi kombináciami výstupných prepínačov. Viacnásobné použitie rovnakého prepínača nebude testované.
  • [3b] Za správne fungovanie kombinácie vstupných a výstupných prepínačov súčasne. Program bude testovaný tak, že bude spúšťaný v rôznych kombináciách vstupných a výstupných prepínačov. Viacnásobné použitie rovnakého prepínača nebude testované.

Nezabudnite, že nutnou podmienkou je, aby bol váš program kompilovateľný prekladačom gcc so zapnutým prepínačom -Wall bez chýb a upozornení (0 errors a 0 warnings). Vo vlastnom záujme si toto otestujte.

Konzultovanie zadaní

Všetky vaše otázky smerujúce k zadaniu č.3 môžete zasielať na STUBA e-mailové adresy svojich cvičiacich alebo sa zapojiť do živej diskusie na našom Discord serveri (invite linka bola poslaná cez AIS) v kanáli #zadanie3.

Stay tuned.