Jazyk C 2013 – 11. cvičenie [Slová zo vstupu na samostatné riadky, Knižnica pre zásobník]

Slová do riadkov

Vytvorte program, ktorý každé slovo zo vstupu zapíše na samostatný riadok.

Ukážkový vstup:

By this art you may contemplate the variations of the 23 letters...
-- The Anatomy of Melancholy, part 2, sect. II, mem. IV

Ukážkový výstup:

By
this
art
you
may
contemplate
the
variations
of
the
letters
The
Anatomy
of
Melancholy
part
sect
II
mem
IV

Idea

  • Načítavajme po znakoch zo vstupu.
    • Ak je znak písmeno, zapíšme ho na výstup.
    • Ak je to medzera, zapíšme na výstup znak konca riadka.
    • Ak je to iný znak, ignorujme ho.
  • Ak ide viac medzier po sebe, pomocou príznaku zapíšme len prvú medzeru. Príznak resetnime po prvom písmene.

Zdrojový kód [verzia 1]

#include<stdio.h>
#include<ctype.h>

int main() {
        int znak;
        int bola_medzera = 0;

        while(1) {
                znak = getc(stdin);
                if(znak == EOF) {
                    break;
                }
                if(isalpha(znak)) {
                        bola_medzera = 0;
                        putc(znak, stdout);
                }
                if(isspace(znak)) {
                        if(!bola_medzera) {
                                putc('\n', stdout);
                        }
                        bola_medzera = 1;
                }
        }

        return 0;
}
  • znak načítame cez getc().
    • alternatívne cez ekvivalentnú fgetc()
    • alternatívne cez ekvivalentnú getchar() bez parametra
  • pozor: funkcia nevracia char, ale int!
  • na zistenie kategórie znaku využijeme funkcie is****() z ctype.h.
  • znak zapíšeme cez putc()
    • alternatívne cez ekvivalentnú fgetc()
    • alternatívne cez ekvivalentnú getchar() bez parametra

Zdrojový kód [verzia 2]

Cyklus vieme prepísať krásnou céčkoidnou konštrukciou, kde načítanie a porovnanie vybavíme jedným šmahom:

while( (znak = getc(stdin)) != EOF  ) {         
    ...
}

Megavýsledok

Program vieme prepojiť s počítadlom frekvencií:

./slova_na_riadky < babel.txt | ./frekvencie | sort -n

Výsledný zdroják:

#include<stdio.h>
#include<ctype.h>

int main() {
        int znak;
        int bola_medzera = 0;

        while( (znak = getc(stdin)) != EOF  ) {
                if(isalpha(znak)) {
                        bola_medzera = 0;
                        putc(znak, stdout);
                }
                if(isspace(znak)) {
                        if(!bola_medzera) {
                                putc('\n', stdout);
                        }
                        bola_medzera = 1;
                }
        }

        return 0;
}

Knižnica pre zásobník

Vytvorte knižnicu pre zásobník (stack) znakov.

Projekt bude pozostávať z troch súborov:

  • modul knižnice:
    • hlavičkový súbor: možno chápať ako historického predchodcu interfejsov v Jave. Je v samostatnom súbore a obsahuje:
      • deklarácie dátových typov knižnice: u nás zásobník
      • hlavičky funkcií, ktoré sú k dispozícii
    • implementačný súbor: obsahuje implementácie funkcií v hlavičkovom súbore.
  • demonštračný súbor: obsahuje metódu main() a zdemonštruje knižnicu

Hlavičkový súbor zasobnik.h

struct polozka {
        char znak;
        struct polozka * dalsi;
};

typedef struct polozka * ZASOBNIK;

ZASOBNIK zasobnik_novy(void);

int zasobnik_je_prazdny(ZASOBNIK zasobnik);

/*
neskor doimplementujeme:

int zasobnik_push(ZASOBNIK zasobnik, char c);

char zasobnik_pop(ZASOBNIK zasobnik);
*/
  • Všimnime si, ako sme premenovali dátový typ struct polozka * na ZASOBNIK, čo sprehľadní zápisy.
  • Využijeme konštrukciu typedef, kde uvedieme názov dátového typu a alias.
  • Názvy funkcií musia byť jednoznačné:
    • v C neexistujú balíčky/menné priestory, a teda názvy funkcií musia byť jednoznačné vzhľadom na celý projekt a všetky knižnice, ktoré využíva.
    • viď tiež filozofiu v PHP a názvy funkcií ako mysql_​fetch_​array()
  • funkcia zasobnik_novy(void) explicitne uvádza nulový počet parametrov
    • deklarácia ZASOBNIK zasobnik_novy() hovorí, že na počte parametrov pri volaní nezáleží

Implementačná trieda zasobnik.c

Zdrojový kód

#include"zasobnik.h"
#include<stdio.h>

ZASOBNIK zasobnik_novy(void) {
        return NULL;
}

int zasobnik_je_prazdny(ZASOBNIK zasobnik) {
        return zasobnik == NULL;
}
  • v implementačnej triede includeneme hlavičkový súbor zasobnik.h
    • musíme vidieť dátovú štruktúru pre zásobník
    • zároveň sa z hlavičkového súboru stanú funkčné prototypy funkcií, ktoré implementujeme a už nemusíme dávať pozor na prípadné poradie funkcií
  • pozor, nevyužívame #include<...>, ale #include"..."
    • zobáková notácia hľadá hlavičkové súbory v štandardných systémových lokáciách. Používa sa pre systémové knižnice.
    • úvodzovková hľadá v aktuálnom adresári.
  • includnime však systémovú knižnicu stdio.h, keďže NULL je konštanta z tejto knižnice.
  • v implementácii sme sa rozhodli, že prázdny zásobník je reprezentovaný NULL pointerom
  • knižnica neobsahuje metódu main(): knižnica je samostojná, nespustiteľná, to je úlohou programu, ktorý ju využíva

Kompilácia knižnice

Samostojná knižnica sa skompiluje cez:

gcc -c zasobnik.c -o zasobnik.o
  • Parameter -c vypne linker. (Podrobnosti o fázach kompilovania v samostatnom článku.
  • z kompilácie vypadne objektový súbor zasobnik.o.

Demonštračný súbor

Demo zasobnik_demo.c bude krátke:

#include<stdio.h>
#include"zasobnik.h"

int main() {
        ZASOBNIK z = zasobnik_novy();
        if(zasobnik_je_prazdny(z)) {
                puts("Zasobnik je prazdny");
        } else {
                puts("Zasobnik NIE JE prazdny");
        }
        return 0;
}
  • knižnicu zavedieme includenutím jej hlavičkového súboru
  • veselo voláme dátové typy

Kompilácia dema

  • Možnosť 1: Ak máme k dispozícii objektový súbor knižnice:

    gcc zasobnik_demo.c zasobnik.o -o zasobnik_demo
    
    • gcc skompiluje zasobnik_demo a vytvorí objektový súbor
    • a zároveň ho prelinkuje s objektovým súborom knižnice zasobnik.o
    • výsledkom je spustiteľná binárka zasobnik_demo
  • Možnosť 2: Ak máme k dispozícii zdroják knižnice

    gcc zasobnik_demo.c zasobnik.c -o zasobnik_demo
    
    • gcc skompiluje všetky zdrojáky, prelinkuje ich a vytvorí spustiteľnú binárku

Ďalšie zdroje

Pridaj komentár

Vaša e-mailová adresa nebude zverejnená. Vyžadované polia sú označené *