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
- alternatívne cez ekvivalentnú
- pozor: funkcia nevracia
char
, aleint
! - na zistenie kategórie znaku využijeme funkcie
is****()
zctype.h
. - znak zapíšeme cez
putc()
- alternatívne cez ekvivalentnú
fgetc()
- alternatívne cez ekvivalentnú
getchar()
bez parametra
- alternatívne cez ekvivalentnú
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.
- hlavičkový súbor: možno chápať ako historického predchodcu interfejsov v Jave. Je v samostatnom súbore a obsahuje:
- 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 *
naZASOBNIK
, č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ží
- deklarácia
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
include
neme hlavičkový súborzasobnik.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ďžeNULL
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
include
nutí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
skompilujezasobnik_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