Evropský polytechnický institut, s.r.o. 1. soukromá vysoká škola na Moravě Kunovice
Teoretické základy informatiky pro ekonomy II.
Oldřich Kratochvíl Jindřich Petrucha Robert Jurča
2014
Evropský polytechnický institut, s.r.o. 1. soukromá vysoká škola na Moravě Osvobození 699, 686 04 Kunovice e-mail:
[email protected] http://www.edukomplex.cz/epi
Teoretické základy informatiky pro ekonomy II.
Oldřich Kratochvíl Jindřich Petrucha Robert Jurča
2013
Autor: Prof. Ing. Oldřich Kratochvíl, Ph.D., CSc., MBA, Dr.h.c. Ing. Jindřich Petrucha, Ph.D. Ing. Robert Jurča, Ph.D.
Název: Teoretické základy informatiky pro ekonomy II.
Vydavatel: © Evropský polytechnický institut, s.r.o. Kunovice 2014
ISBN 978-80-7314-303-9
O autorech Oldřich Kratochvíl se narodil v ČR v krásném prostředí Moravského Slovácka. Absolvoval v roce 1971 na Vysoké škole dopravní v Žilině ve Slovenské republice. Po skončení studia vysoké školy pracoval nejprve jako asistent na této vysoké škole v Žilině, následovalo působení v telekomunikacích, odkud přešel do oblasti zavádění informačních technologií do zemědělství. Absolvoval pedagogické studium na UJEP Brno. V roce 1991 založil jednu z prvních soukromých středních odborných škol v ČR a založil také první vyšší odbornou školu v ČR. V roce 1995 vedl akreditaci první soukromé vysoké školy pod irskou legislativou v ČR a v roce 1999 založil druhou soukromou vysokou školu v ČR pod českou legislativou. Byl prvním předsedou Asociace soukromých středních škol v ČR a Asociace soukromých vysokých škol v ČR. V roce 1991 absolvoval stáž na univerzitách v Kanadě. Spolupracoval při zavádění soukromého vysokého školství v ČR s KL Transfer a PTH Eidhoven v Nizozemí. Od roku 1997 spolupracuje s REA Moskva a od roku 2006 s MOSAP Moskva a Vysokou školou v Podolsku v Rusku. Vysoká škola REA Moskva mu roku 2005 udělila čestnou vědeckou hodnost Doctor honoris causa, v roce 2007 byl jmenován Honorary Professor pro obor zahraniční obchod na MOSAP v Moskvě, kde je členem katedry zahraničního obchodu. MBA absolvoval na Rushmore university v roce 2008. V roce 2011 obhájil titul CSc na REU AP v Moskvě. V roce 2012 byl jmenován profesorem na Rushmore University v USA a Chartered Management Institute v UK. Od roku 1991 do roku 2006 zastával funkci ředitele střední školy, od roku 1991 až doposud působí jako ředitel Vyšší odborné školy právní a od roku 1991 působí jako rektor Soukromé vysoké školy EPI, s.r.o. V pedagogické práci, výzkumu a publikaci se specializuje na management, strategický management, marketing, mezinárodní marketing, komunikaci, pedagogiku, oborové didaktiky a rozvoj technologií ve školství a přímé zahraniční investice. Byl členem pléna Rady vysokých škol v ČR a členem České konference rektorův ČR.
Ing. Jindřich Petrucha, PhD. se narodil v ČR v Uherském Hradišti. Absolvoval Střední průmyslovou školu strojní v Uherském Hradišti. V roce 1978 studoval na VUT Brno fakultu strojní kde se seznámil s problematikou počítačů. Po ukončení studia v roce 1983 nastupuje do praxe v podniku MESIT (Měřící a signalizační technika) jako vývojový pracovník. Zde se věnoval oblasti nasazení mikroprocesorů do řídících systémů, které tato firma vyvíjela pro letecká zařízení. Protože firma v této době vyvíjela svůj mikroprocesorový systém na bázi prvních procesorů 8080, byl vyslán na další studia na ČVUT Praha, kde na fakultě elektro absolvoval postgraduální studium v oboru mikropočítačů. Po roce 1991 odešel pracovat jako vyučující do Evropského polytechnického institutu v Kunovicích, kde stál u zrodu vyššího odborného školství. V roce 1992 se zúčastnil zahraniční stáže v Hogeschool Eidhoven v Holansku, která byly zaměřena na principy výuky v zahraničních školách a na tvorbu osnov pro různé oblasti výuky. Škola v tomto období zahájila spolupráci s irskou organizaci NCEA, která realizovala společně se školou akreditaci bakalářského studia pod irskou legislativou. V roce 1999 zahájil doktorská studia na MZLU v Brně obor ekonomická informatika pod vedením Doc. A.Motyčky, který jej odborně profiloval k vědecké činnosti. Tento směr vědecké práce se snažil udržovat v průběhu doktorského studia tak aby vyústil v jeho disertační práci. Dílčí poznatky získával na různých vědeckých konferencích (ICSC, MENDEL, NOSTRADAMUS apod.), kde také publikoval své přínosy k aplikaci simulátorů neuronových sítí. V současné době pracuje na ústavu aplikované informatiky na Evropském polytechnickém institutu, kde vede výzkumnou činnost zabývající se optimalizačními procesy. V pedagogické oblasti aplikuje výzkum do praxe v předmětech jako jsou operační systémy, programovací jazyky, internetové technologie. Zaměřuje se na zkoumání nových trendů při
aplikaci mobilních technologií a jejich spojení při pedagogické činnosti. Aplikuje výsledky do praxe při zavádění modulů informačního systému EPI. Ing. Robert Jurča, PhD. se narodil v ČR v Uherském Hradišti. Absolvoval Střední stavební školu ve Zlíně a Fakultu managementu a ekonomiky ve Zlíně ve studijním oboru Management a ekonomika. Po skončení vysoké školy v roce 2001 nastoupil na Soukromé gymnázium a střední odbornou školu, s.r.o. a Evropský polytechnický institut, s.r.o. v Kunovicích, kde postupně působil jako asistent a odborný asistent. V letech 2008 - 2011 studoval na Slovenské technické univerzitě v Bratislavě doktorandské studium ve studijním oboru odborová didaktika.
Ve své pedagogické a výzkumné práci se specializuje na informační systémy a grafiku.
Obsah
ÚVOD................................................................................................................................................................5 1
PRÁCE SE SOUBORY..........................................................................................................................6 1.1 1.2 1.3 1.4 1.5 1.6 1.7 1.8
2
ŠIFROVÁNÍ A KRYPTOGRAFIE ....................................................................................................81 2.1 2.2 2.3 2.4 2.5 2.6 2.7
3
ZÁKLADNÍ POJMY ............................................................................................................................6 PRÁCE SE SOUBORY .........................................................................................................................7 OPAKOVÁNÍ NĚKTERÝCH DOPOSUD ZÍSKANÝCH POZNATKŮ ..........................................................21 PRAKTICKÉ APLIKACE....................................................................................................................23 PRÁCE S EOF.................................................................................................................................44 TVORBA DATABÁZÍ ........................................................................................................................61 PRÁCE S PARAMETREM „R+“ .........................................................................................................73 VYTVOŘENÍ ZÁLOŽNÍHO SOUBORU ................................................................................................78
CÍLOVÉ ZNALOSTI A DOVEDNOSTI..................................................................................................81 HISTORIE ŠIFROVÁNÍ......................................................................................................................81 MODERNÍ KRYPTOGRAFIE ..............................................................................................................81 Bezpečnostní cíle kryptografie .................................................................................................82 Základní pojmy.........................................................................................................................83 Symetrické a asymetrické šifry .................................................................................................83 KONTROLNÍ OTÁZKY .....................................................................................................................84
ELEKTRONICKÝ PODPIS ...............................................................................................................85 3.1 3.2 3.3 3.4 3.5
ELEKTRONICKÝ PODPIS ..................................................................................................................85 ELEKTRONICKÝ PODPIS A JEHO UŽITÍ .............................................................................................85 CERTIFIKAČNÍ AUTORITA ...............................................................................................................87 ZAVEDENÍ ELEKTRONICKÉHO PODPISU ..........................................................................................87 ZÁKON O ELEKTRONICKÉM PODPISU ..............................................................................................88
ZÁVĚR ...........................................................................................................................................................89
Úvod Tento studijní text navazuje na text „Teoretické základy informatiky pro ekonomy I. I tento text je součástí IGS a slouží jako výstup výzkumu předmětové didaktiky vysokoškolského předmětu Teoretické základy informatiky. Úkolem tohoto výzkumu je umožnit manažerům, podnikatelům a dalším řídícím pracovníkům vybudovat si mezioborové znalosti z oblasti aplikované informatiky, které budou moci využít v těchto profesích. Očekáváme, že absolventi budou schopní nejen využívat nejnovější software pro inovaci procesů v podnikové sféře, ale dokáží také takový software projektovat. Absolventi budou specialisté v oblastech, které vyžadují tyto pracovní pozice na počátku 21. století. Zatímco v první části studia se posluchači naučili formulovat algoritmy pro řešení praktických problémů a převádět je do vývojového diagramu a jednoduchých struktur programu, v této druhé části se čtenář naučí pracovat s proměnnou typu soubor a tvořit algoritmy pro řešení takových úloh, v nichž si již čtenář začíná vytvářet praktické aplikace pro svou práci. Na tento studijní text navazují další studijní texty – Úvod do programování, Operační systémy, Databázové systémy, Programování v PHP a HTML a Objektové programování.
5
1 Práce se soubory 1.1 Základní pojmy Doposud jsme data ukládali do proměnných typu integer, char, atd. nebo do polí. Vypnutím počítače tato data ztrácíme. Proto potřebujeme strukturu dat, která se uchová i po vypnutí počítače. Mluvíme o souborech. V textovém editoru „Poznámkový blok“ se setkáváte se souborem .txt. Jde o textový soubor, v němž se mohou nacházet znaky, řetězce znaků i čísla. V jazyku C můžeme vytvořit textový soubor, který má předem definovanou strukturu. V praxi často potřebujeme vytvořit soubor, v němž budeme mít trvale uloženy a zpřístupněny data pro každého pracovníka např.: příjmení [0]
jméno [0]
mzda [0]
příjmení [1]
jméno [1]
mzda [1]
……
17 000
……
plat.txt věta
Kotek
věta
Jan
24 000
Janků
Petra
plat.txt věta
věta
Soubor má oproti poli výhodu v tom, že když ho jednou vytvoříme a uložíme, můžeme ho kdykoliv znovu přečíst, opravit, využít údaje. Do souboru můžeme data buď zapisovat (write), nebo je ze souboru číst (read). Vždy však přes aktivaci proměnné fd typu FILE, jak vidíme v následujících obrázcích. EOF
EOF plat.txt
w
1
plat.txt výpis fprintf (fd ……);
fd
fd
fd
r
2
výpis fscanf (fd, "%d" ….."r");
fd
fd
fd
naplnění scnaf (……"w"); p1
p1
p1
Datový tok Obr. č. 1: Zápis dat do souboru Zdroj: vlastní
proměnné - textovy(ASCII znaky) - binární
p1
p1
p1
proměnné
Datový tok Obr. č. 2: Čtení dat ze souboru Zdroj: vlastní
Tok dat je připojený přes fd k souboru plat.txt na zápis(w). Toto „ukazovátko“ (kanál) se posunuje vždy po provedeném zápisu dat ( 1 po provedeném načtení viz obr. č. 2 2 ) dat. Proměnnou typu FILE fd zřídíme a připojíme k souboru plat.txt příkazem: a) na zápis fd=fopen("plat.txt","w"); ……. viz obr. č. 1 b) na čtení fd=fopen("plat.txt","r"); ……… viz obr. č. 2
Proměnnou fd odpojíme od textového souboru (zrušíme) příkazem fclose(fd);
6
Hodnotu do souboru ukládáme příkazem fprintf(fd,"%d\n",p1); přes proměnnou (v našem případě p1): Hodnotu z proměnné fd načteme do proměnné p1 příkazem: fscanf(fd,"%d",&p1); EOF
Konec souboru označuje značka EOF. Obecně máme k dispozici následující režimy práce se souborem: Režim "r" "w" "a" "rb" "wb" "ab" "r+" "w+" "a+"
Význam Otevře textový soubor pro čtení. Vytvoří textový soubor pro zápis. Otevře textový soubor pro přepisování. Otevře binární soubor pro čtení. Vytvoří binární soubor pro zápis. Otevře binární soubor pro přepisování. Otevře textový soubor pro čtení/zápis. Vytvoří textový soubor pro čtení/zápis. Otevře textový soubor pro čtení/přepisování.
Aktuální pozice (místo v souboru, kde se bude provádět další operace se souborem (čtení, zápis dat, atd.)
V následujícím textu se naučíme pracovat s parametry „r“, „w“, a „r+“. Nové poznatky budeme získávat prostřednictvím řešení konkrétních úloh s tím, že je důraz kladen na propojení vývojového diagramu, práce paměti a řadiče, a přepis do jazyka C.
1.2 Práce se soubory V této kapitole se naučíme vytvořit soubor, zapsat do souboru a číst ze něj.
Úkol č. 1 Vytvořte textový soubor plat.txt a do něj zapište hodnotu mzdy pracovníka (celočíselná hodnota). Tento soubor přečtete v textovém editoru. Metodický pokyn: Nejprve si musíme definovat proměnnou typu FILE, fd 1, dále musíme proměnnou fd připojit k souboru plat.txt na zápis (w) 2 . Načteme hodnotu mzdy do proměnné p1 3 . Dále potřebujeme obsah proměnné p1 zapsat do f(d) 4 . Tím se automaticky zapíše obsah p1(mzda) do souboru plat.txt. Úkol je splněn a zbývá jen fd odpojit 6 od souboru plat.txt.
7
5
Řešení: Vývojový diagram
Zápis do jazyka C #include <stdio.h> main () {
Z
1
int p1; FILE *fd;
Deklarace proměnných p1….. typu INT fd ….. typu FILE
14 500 2
Připojím fd k souboru v režimu ZÁPIS
EOF
plat.txt odpojení
připojení
fd=fopen("plat.txt","w");
fd
printf("Zadej mzdu:"); scanf("%d",&p1);
3
14 500
Načtení platu do p1 p1
5
fprintf(fd,"%d\n",p1); Zápis p1 do fd a do souboru
4
Odpojení fd od souboru + zápis eof
6
povolení
fclose(fd);
system("PAUSE"); Zastavení programu } K Obr. č. 3: Vývojový diagram programu Zdroj: vlastní
Pozn: Funkce fopen( ) používá klasický soubor studio.h. Je-li fopen ( ) neúspěšná, vrací nulový ukazatel – NULL. Př:
8
FILE *fd; if((fcp)= fopen("pracivbuci.txt", "r")) ==NULL {printf ("chyba pri otevirani souboru\n");}
#include <stdio.h> main () { int p1; FILE *fd; 1
hodnota
EOF
plat.txt Deklarujeme fd
2
fd=fopen("plat.txt","w");
"w"
1
hodnota
Připojení na zápis
fd
scanf("%d",&p1);
hodnota
Zanést hodnoty
3
p1
Povolit zápis fd plat.txt 4
fprintf(fd,"%d\n",p1);
fclose(fd); //zrušení fd system("PAUSE");
6
Ukončit propojení fd na plat.txt
Obr. č. 4: Vývojový diagram zápis do souboru Zdroj: vlastní
}
Nově vytvořený textový soubor bude mít následující strukturu: p1
EOF
označení konce souboru
plat.txt
O tom, že jsme soustavu plat.txt vytvořili se lze přesvědčit výpisem textového editoru:
Obr. č. 6: Výpis obrazovky programu Zdroj: vlastní
Pro ověření lze takový soubor plat.txt vypsat v textovém editoru.
Obr. č. 5: Výpis programu v C Zdroj: vlastní
Obr. č. 7: Výpis textového editoru Zdroj: vlastní
9
Úkol č. 2
V úloze č. 1 jsme vytvořili soubor plat.txt. Nyní chceme v něm uloženou hodnotu přečíst a vytisknout na obrazovku. Vytvořte vývojový diagram, převeďte do jazyka C, zkompilujte a ověřte funkčnost programu. Metodický pokyn: 1. Musíte deklarovat proměnnou fd pro čtení uložené hodnoty v plat.txt prostřednictvím p1. 2. Použijte příkazy:
fd=fopen("plat.txt","r"); fscanf(fd,"%d",&p1);
Řešení: Vývojový diagram
Zápis do jazyka C #include <stdio.h> main () {
Z
Deklarace proměnných p1….. typu INT Fd ….. typu FILE
int p1; FILE *fd;
14 500 Připojím fd k souboru v režimu ČTENÍ
EOF fd=fopen("plat.txt","r");
„r“
Připojení na čtení
14 500 fd
Načtení fd do p1
Povolení čtení položky
fscanf(fd,"%d",&p1); 14 500
p1
Odpojení fd
Tisk p1
fclose(fd);
14 500
printf("%d\n",p1);
Zastavení programu
system("PAUSE"); K
Obr. č. 8: Vývojový diagram programu Zdroj: vlastní
10
K
}
Obr. č. 9: Výpis souboru plat.txt na obrazovku Zdroj: vlastní
Obr. č. 10: Výpis programu Zdroj: vlastní
Úkol č. 3 Zadání: Vytvořte prázdný soubor pracov1.txt Metodický pokyn: Prázdný soubor je takový soubor, který obsahuje jen EOF. Následující soubor pracov1.txt je prázdný. EOF pracov1.txt
Chceme-li vytvořit prázdný soubor, stačí otevřít soubor na zápis a následně jej uzavřít. Řešení: Vývojový diagram
Program v jazyku C
Z
Otevření souboru pracov1.txt na zápis
main () { FILE *fd;
Uzavření souboru pracov1.txt
fd=fopen("pracov1.txt","w"); fclose(fd); system("PAUSE");
Zastavení programu
} K Obr. č. 11: Vývojový diagram programu Zdroj: vlastní
Obr. č. 12: Výpis programu v C Zdroj: vlastní
11
Obr. č. 13: Výpis textového editoru Zdroj: vlastní
Úkol č. 4 Zadání: Upravte program z předcházejícího příkladu a odstraňte z něj deklaraci souboru (FILE *fd;). Jak bude program pracovat? Zdůvodněte. Metodický pokyn: Odtraníme deklaraci FILE *fd; a spustíme program. Program v C: main () { fd=fopen("pracov1.txt","w"); fclose(fd); system("PAUSE"); }
Obr. č. 14: Výpis programu v C Zdroj: vlastní
Závěr: Program nebude funkční, protože jsme nedeklarovali proměnnou fd, kterou potřebuje příkaz fd=fopen( ).
Úkol č. 5 Zadání: Vytvořte soubor pracov.txt o struktuře: příjmení [1]
jméno [1]
mzda [1]
příjmení [2]
jméno [2]
mzda [2]
EOF
pracov.txt věta č. 1
věta č. 2
Soubor bude evidovat údaje o pěti pracovnících Mzda bude celočíselná hodnota. Příjmení a jméno může mít délku max 30. znaků. Tento soubor naplňte, soubor uzavřete a obsah souboru pracov.txt vypište na obrazovku a přečtěte v textovém editoru Metodický pokyn: Do souboru máme napsat 5 položek, s možností rozšířit úpravu zápisu až na 100 položek. K tomuto účelu se hodí cyklus for. I v tomtéž případě si po vytvoření souboru obsah těchto souborů vypište prostřednictvím textového editoru. Pro uložení položek si zvolíme proměnné typu pole, se kterým se dobře pracuje v cyklu postupného načítání pracovníků.
12
Varianta A: V této variantě načteme údaje pro každého pracovníka samostatnými příkazy. Vývojový diagram:
Z
Databáze v MC 1
Deklarace proměnných
prijmeni1 [30]
jmeno1 [30]
mzda1
prijmeni2 [30]
jmenoi2 [30]
mzda2
prijmeni3 [30]
jmeno3 [30]
mzda3
prijmeni4 [30]
jmeno4 [30]
mzda4
prijmeni5 [30]
jmeno5 [30]
mzda5
příjmení [5] [30] …. char jméno [5] [30] …. char mzda [5] …. int FILE *fd 2
Připojení proměnné fd k souboru pracov.txt na zápis
pracov.txt w fd 3
Načtení dat o jednotlivých pracovních do proměnných
pracov.txt
4
fd
Zapsání proměnných do souboru pracov.txt
fd
fd
prijmeni1 jmeno1 5
Odpojení fd od souboru pracov.txt
mzda1
K
Obr. č. 15: Vývojový diagram programu Zdroj: vlastní
Popis práce vývojového diagramu a programu v jazyku C: 1
V úvodní části deklarujeme všechny proměnné.
2
Otevřeme soubor pracov.txt na zápis (připojíme fd).
3
Načteme data jednotlivých pracovníků do příslušné proměnné. Vytvoříme databázi prijmeni1 – mzda3.
4
Zapíšeme postupně tyto proměnné do souboru pracov.txt.
5
Soubor pracov.txt zavřeme (odpojíme fd).
13
Program v jazyku C: #include <stdio.h> main () { char prijmeni1 [30], prijmeni2[30], prijmeni3[30], prijmeni4[30], prijmeni5[30]; char jmeno1[30], jmeno2[30], jmeno3[30], jmeno4[30], jmeno5[30]; int mzda1, mzda2, mzda3, mzda4, mzda5; FILE *fd; fd=fopen("pracov.txt","w");
1
2
printf("pracovnik 1:"); scanf("%s",prijmeni1); scanf("%s",jmeno1); scanf("%d",&mzda1); printf("pracovnik 2:"); scanf("%s",prijmeni2); scanf("%s",jmeno2); scanf("%d",&mzda2); printf("pracovnik 3:"); scanf("%s",prijmeni3); scanf("%s",jmeno3); scanf("%d",&mzda3); printf("pracovnik 4:"); scanf("%s",prijmeni4); scanf("%s",jmeno4); scanf("%d",&mzda4); printf("pracovnik 5:"); scanf("%s",prijmeni5); scanf("%s",jmeno5); scanf("%d",&mzda5);
prijmeni1
jmeno1
mzda1
prijmeni2
jmeno2
mzda2
prijmeni3
jmeno3
mzda3
prijmeni4
jmeno4
mzda4
prijmeni5
jmeno5
mzda5
3
fprintf(fd,"%s\n",prijmeni1); fprintf(fd,"%s\n",jmeno1); fprintf(fd,"%d\n",mzda1); fprintf(fd,"%s\n",prijmeni2); fprintf(fd,"%s\n",jmeno2); fprintf(fd,"%d\n",mzda2);
…… fd
prijmeni1 fprintf(fd,"%s\n",prijmeni3); fprintf(fd,"%s\n",jmeno3); fprintf(fd,"%d\n",mzda3); fprintf(fd,"%s\n",prijmeni4); fprintf(fd,"%s\n",jmeno4); fprintf(fd,"%d\n",mzda4); fprintf(fd,"%s\n",prijmeni5); fprintf(fd,"%s\n",jmeno5); fprintf(fd,"%d\n",mzda5); fclose(fd); 5 system("PAUSE"); }
14
fd
fd
jmeno1
pracov.txt
věta 1
mzda1
fd
prijmeni2 věta 2 4
Obr. č. 16: Vývojový diagram programu Zdroj: vlastní
Pozn.: Funkce fcloce ( ) zavře soubor spojený s fd a odpojí datový proud od souboru. Systém většinou zapisuje data na disk po sektorech přes buffer v paměti. Buffer je vyprazdňován až po jeho naplnění. Funkce fclose ( ) zapíše na disk automaticky všechna zapsaná data v čátečně naplněném butteru. Mluvíme o tzv. vyprázdnění bufferu. Při neúspěchu vrací fclose ( ) nulu. Nastane-li chyba, vrací EOF.
Obr. č. 17: Výpis obrazovky programu Zdroj: vlastní
15
Varinata B: V této variantě načteme údaje pro každého pracovníka s využitím cyklu. Řešení: Vývojový diagram
Program v jazyku C:
Z 1
Deklarace proměnných i, n … int příjmení [100] [30] …. char jméno [100] [30] …. char mzda [100] …. int FILE *fd 2
Stanovte počet pracovníků n=5
#include <stdio.h> main () { //blok 1
1
Deklarace proměnných
int i,n; char prijmeni [100][30]; char jmeno [100][30]; int mzda [100]; FILE *fd;
//blok
2
2
Stanovíme si počet pracovníků, pro které chceme data evidovat (max=100)
3
K souboru prac.txt proměnnou fd na zápis.
4
V cyklu for načteme údaje o 5 pracovnících (u každého příjmení, jméno a mzdu) z klávesnice a přes fd zapíšeme do souboru pracov.txt.
n=5;
3
//blok
Připojení proměnné fd k souboru pracov.txt na zápis
3
fd=fopen("pracov.txt","w");
//blok
4
i=1; n; +1
4
for(i=1;i<=n;i++) {
printf("pracovnik %d:",i); scanf("%s",prijmeni[i]); scanf("%s",jmeno[i]); scanf("%d",&mzda[i]); fprintf(fd,"%s %s %d\n",prijmeni[i],jmeno[i],mzda[i]);
Načti prijmeni, jmeno, datumnarozeni a zápis do pracov.txt }
i 5
Odpojení fd od souboru pracov.txt
//blok fclose(fd); system("PAUSE");
K
Obr. č. 18: Vývojový diagram programu Zdroj: vlastní
16
připojíme
5
}
Jakmile jsou data všech pracovníků načtena můžeme fd odpojit.
Tento stručný diagram nyní rozšíříme a popíšeme, co se děje v paměti a jak pracuje řadič: Z int
1
i
Deklarace proměnných
int n
int i, n pole příjmení [100] [30] jméno [100] [30] mzda [100] FILE *fd
Příjmení [0] Příjmení
Příjmení [1]
………..
Příjmení [29]
Jméno [0] Jméno [100]
Jméno [1]
………..
Jméno [29]
Mzda [0] Mzda
Mzda [1]
………..
Mzda [29]
fd 2
n=5
5 n 3
Otevři soubor pracov.txt na zápis
EOF pracov.txt
w
4
fd
Načtení dat o jednotlivých pracovnících
i = 1, n, 1
i=3 4 5
i=2
i=1
i=6
Pracovník: 5
Příjmení [i]
prijmeni2
prijmeni1
Jméno [i]
Martin n
Jan
jemno2
jmeno1
Mzda [i]
13400
11900
mzda2
mzda1
Zápis Příjmení [i], Jméno [i], Mzda [i] přes fd do pracov.txt
Louka
EOF
Palus
Louka
Jan
11900
Palus
Martin
13400
EOF
pracov.txt Mzda [2] Jméno[2]
i
Příjmení [2] Mzda [1]
Uzavři soubor
5
Jméno[1] Příjmení [1]
Z Obr. č. 19: Vývojový diagram programu Zdroj: vlastní
Louka
EOF
Louka
Jan
EOF
Louka
Jan
11900
EOF
17
V tomto programu jsme po zadání dat pracovníků tyto údaje prostřednictvím proměnné fd (vidíme, že jde o strukturovanou proměnnou) zapsali do souboru pracov.txt. Jeho údaje již zůstanou k dispozici i po skončení práce programu v příslušném souboru. Dále jsme vývojový diagram doplnili při čtení dat o pracovníkovi využitím cyklu for. Jakmile cyklus for dosáhne i = 6, uzavře se soubor pracov.txt (odpojí fd, doplní EOF) a program práci ukončí. V následujícím textu vidíme výpis programu, obrazovky v průběhu práce programu a výpis souboru pracov.txt v textovém editoru.
Obr. č. 20: Výpis programu v C Zdroj: vlastní
Obr. č. 21: Výpis obrazovky programu Zdroj: vlastní
Soubor pracov.txt lze přečíst také textovým editorem.
Obr. č. 22: Výpis souboru pracov.txt v textovém editoru Zdroj: vlastní
Samostatná práce studenta: 1. Doplňte program tak, aby při tisku na obrazovku očísloval pracovníky. 2. Doplňte program tak, aby při tisku výstupní sestavy zarovnal příjmení, jméno, mzda do sloupce. 3. Doplňte program tak, aby příjmení pracovníka bylo vždy na novém řádku.
18
Úkol č. 6 Máme vytvořený soubor pracov.txt pro 5 pracovníků v následující struktuře (viz Úkol č. 5). Obsah tohoto souboru chceme přečíst a vypsat na obrazovku. Metodický pokyn: V tomto případě vycházíme z úkolu č. 2 s tím, že proces čtení položky se musí opakovat až po EOF. Výhodné je využití cyklu. Program bude pracovat se souborem pracov.txt v následující struktuře: Příjmení [1]
Jméno [1]
Mzda [1]
Příjmení [2]
Jméno [2]
Mzda [2]
Příjmení [3]
Jméno [3]
Mzda [3]
Příjmení [4]
Jméno [4]
Mzda [4]
Příjmení [5]
Jméno [5]
Mzda [5]
EOF
Louka Jan pracov.txt
11900
Palus
Martin
13400
Jakubec
Petr
18900
Jansa
David
17800
Landa
Pavel
13900
EOF
pracov.txt
V našem případě
Soubor můžeme samozřejmě vyčíst v textovém editoru. V praktických aplikacích však chceme mít možnost vyčíst soubor v rámci nabídky v MENU. Pro vyřešení tohoto úkolu bude potřeba realizovat následující vývojový program: Z Deklarace proměnných
Kolik chceme načíst pracovníků? n=5
1
2
#include <stdio.h> main () { int i,n; char prijmeni [100][30]; jmeno [100][30]; int mzda [100]; FILE *fd;
i
n 0
1
2
3
29
0
1
2
3
29
0
1
2
3
29
prijmeni [0] prijmeni [1] prijmeni [2] prijmeni [99]
jmeno [0] jmeno [1] jmeno [2] jmeno [99]
n=5; mzda [0] mzda [1] mzda [2]
3
Otevři soubor pracov.txt pro čtení ´r´
mzda [99]
fd=fopen("pracov.txt","r");
EOF
fd
4
Vypiš na obrazovku
pracov.txt
EOF
printf("prijmeni jmeno mzda\n"); Příjmení
Jméno
Mzda
Postupně pro všechny pracovníky z pracov.txt čti Příjmení, Jméno, Mzda a tyto údaje vytiskni a obrazovku Zavři soubor pracov. txt Zastav program
r 5
fd
cyklus čtení a tisku
6
cyklus
uzavření souboru fclose(fd);
pracov.txt
5
system("PAUSE");
8
K
}
Obr. č. 23: Vývojový diagram programu Zdroj: vlastní
19
Tento vývojový diagram je třeba rozpracovat v bodu 5: Z 1
Deklarace proměnných
2
Kolik chceme načíst pracovníků n=5
n=5;
3
Otevři soubor pracov.txt pro čtení ´r´
fd=fopen("pracov.txt","r"); 4
Vypiš na obrazovku Příjmení
Jméno
printf("prijmeni jmeno mzda\n");
Mzda 5
i = 1, 5, 1
for(i=1;i<=n;i++)
5a
Načti z pracov.txt přes fd
fscanf(fd,"%s %s %d",prijmeni[i],jmeno[i], mzda[i]);
prijmeni [i]; jmeno [i]; mzda [i]; 5b
printf("%s %s %d\n",prijmeni[i],jmeno[i], mzda[i]);
Vytiskni na obrazovku prijmeni [i]; jmeno [i]; mzda [i];
i Zavři soubor pracov. txt Zastav program
6
fclose(fd); 7
system("PAUSE");
8
}
K Obr. č. 24: Vývojový diagram programu Zdroj: vlastní Program v jazyku C: #include <stdio.h> main () { int i,n; 1 char prijmeni [100][30]; char jmeno [100][30]; int mzda [100]; FILE *fd; n=5;
/*vytvoř proměnnou funkci fypu FILE*/
2
fd=fopen("pracov.txt","r");
3
/*otevři sobour pracov.txt na čtení*/
printf("prijmeni jmeno mzda\n"); for(i=0;i
4
/* cyklus načtení věty z pracov.txt a její tisk*/
fscanf(fd,"%s%s%d",prijmeni[i],jmeno[i],&mzda[i]); printf("%s%s%d\n",prijmeni[i],jmeno[i],mzda[i]); } fclose(fd); 6 system("PAUSE"); } 8
20
7
Obr. č. 25: Výpis obrazovky programu Zdroj: vlastní
Obr. č. 26: Výpis programu v C Zdroj: vlastní
Samostatná práce studenta: 1. Upravte program tak, aby položky ve výstupní sestavě „příjmení, jméno, mzda“ byly ve sloupcích zarovnány.
1.3 Opakování některých doposud získaných poznatků Data z klávesnice počítače můžeme ukládat do:
a) proměnných Příjmení
Mzda
a ty mohou obsahovat buď znak, např.: char a; nebo řetězec, např. příjmení [30]; nebo číslo, např. int mzda; atd.
21
b)
do strukturované proměnné pole prvky pole
0 Příjmení
1
2
n
název pole
V našem případě může proměnná Příjmení typu pole obsahovat jen prvky typu řetězec znaků např.: char prijmeni [100] [30]; (dvojrozměrné pole, 100 řádků, v každém 30 znaků) Platí zásada, že musí být všechny prvky jednoho pole stejného typu. K plnění pole je mimořádně vhodná struktura cyklu – while, for. Nevýhodou výše uvedených proměnných je, že po skončení programu jejich obsah zmizí. c) soubor Proto má programovací jazyk C možnost uložit vstupní data do tzv. souboru. Pracujeme se souborem typu text (.txt). Základem souboru je strukturovaná věta:
příjmení [0]
jméno [0]
mzda [0]
příjmení [1]
jméno [1]
mzda [1]
EOF
pracovnici.txt věta č. 1
věta č. 2
Proměnná typu pracovnici.txt je strukturovaná proměnná. Může tedy obsahovat jak řetězec znaků, tak čísla. Struktura se však musí pravidelně opakovat. Opakující se úseky nazýváme věty. Soubor pracovnici.txt má dvě věty a je zakončen znakem EOF. Číst i zapisovat do souboru můžeme sekvenčně, přes proměnnou fd, kterou deklarujeme. FILE *fd;
Proměnná fd se posouvá sekvenčně pod prvkem souboru vždy po provedení operace zápis (w), nebo čtení (r).
Pokud máme strukturu textového souboru pracovnici.txt, můžeme do souboru obecně buď data zapisovat, nebo je číst. Opakujeme si stručný popis těchto činností: Kotek
Jan
24 000
Janků
Petra
17 000
EOF
pracovnici.txt věta 1
fd r
w
Přes fd buď čtu ze souboru (r) do proměnné, nebo do souboru zapisuji (w).
p
Obr. č. 27: Mechanismus čtení a zápisu do souboru Zdroj: vlastní
22
věta 2
Zápis: Kotek pracovnici.txt
Kotek Kotek
fd
Kotek p Obr. č. 28: Zápis do prvního prvku souboru
Kotek
Jan Jan
Postup zápisu do souboru: Otevřeme-li textový soubor pracovnici.txt na zápis, učiníme tak příkazem fd=fopen("narozeniny.txt","w"); Mezi fd a prvním prvkem takového souboru je vytvořený otevřený kanál, prostřednictvím něhož se do prvku pole automaticky přesune vše, co se objeví v proměnné. fd. Data z klávesnice přesuneme do proměnné p příkazem scaf() a z proměnné p do fd příkazem fprintf(fd,"%s\n",p); Nyní se proměnná fd přesune před druhý prvek. Do něj chceme zapsat „Jan“. Tento postup se opakuje tak dlouho, dokud příkazem fclose(fd); nezapíšeme na konec souboru znak EOF (stlačením ENTER).
fd
Jan
p
Jan
Obr. č. 29: Zápis do druhého prvku souboru Zdroj: vlastní
atd.
Čtení:
Kotek
Jan
24 000
pracovnici.txt
fd p
Obr. č. 30: Čtení prvku ze souboru Zdroj: vlastní
Postup při čtení souboru: Otevřeme-li textový soubor pracovnici.txt na čtení, učiníme tak příkazem fd=fopen("narozeniny.txt","r"); Mezi fd a prvním prvkem takového souboru je vytvořený otevřený kanál, prostřednictvím něhož se z prvku č. 1 pole automaticky přesunou data do proměnné. fd. Data z proměnné fd se přesunou do proměnné p příkazem scanf(). Nyní se proměnná fd přesune před druhý prvek. Z něj budu číst „Jan“. Tento postup se opakuje tak dlouho, dokud nenarazíme na EOF.
V následujícím textu si tyto dovednosti podrobněji procvičíme.
1.4 Praktické aplikace Úkol č. 7 Vypracujte program P1, který vytvoří soubor narozeniny.txt ve struktuře věty příjmení, jméno, datum narození pro Vaše blízké. Ověřte, že program pracuje správně výpisem prostřednictvím textového editoru. Datum narozenin bude řetězec znaků. Metodika řešení: Využijte při řešení systém zápisu do textového souboru: Nejprve vytvoříme vývojový diagram a program v jazyku C pro evidenci narozenin tří lidí.
23
Zápis: Kotek
EOF
pracovnici.txt
Kotek fd Kotek p
Kotek
Obr. č. 31: Zápis do prvního prvku souboru Zdroj: vlastní
Řešení: Vývojový diagram Program v jazyku C #include <stdio.h> Z
1
main ()
2
{ Deklarace proměnných
3
4
6
7
5
1
2
3
char prijmeni1[30],prijmeni2[30],prijmeni3[30]; char jmeno1[30],jmeno2[30],jmeno3[30];
4
5
char datumnarozeni1[30], datumnarozeni2[30], datumnarozeni3[30]; FILE *fd;
7
printf("Zadej prijmeni jmeno a udaje oddeluj znakem MEZERA \n"); printf("Zadej datum narozeni ve tvaru RRRR-MM-DD \n"); printf("Zadavani kazdeho cloveka ukonci prikazem ENTER \n\n "); Otevřeme soubor narozeniny.txt na zápis
8
Načtení hodnot z klávesnice do proměnné prijmeni, jmeno, datumnarozeni
9
fd=fopen("narozeniny.txt","w");
scanf("%s%s%s",prijmeni1,jmeno1,datumnarozeni1);
9
10
scanf("%s%s%s",prijmeni2,jmeno2,datumnarozeni2);
10
11
scanf("%s%s%s",prijmeni3,jmeno3,datumnarozeni3);
11
12 Zápis vytvořených proměnných přes fd do 13 souboru narozeniny.txt 14
Uzavření souboru (fd); 15
Zastavení programu
16
17 K
Obr. č. 32: Vývojový diagram programu Zdroj: vlastní
24
8
fprintf(fd,"%s\n%s\n%s\n",prijmeni1,jmeno1, datumnarozeni1);
12
fprintf(fd,"%s\n%s\n%s\n",prijmeni2,jmeno2, datumnarozeni2);
13
fprintf(fd,"%s\n%s\n%s\n",prijmeni3,jmeno3, datumnarozeni3);
14
fclose(fd); 15
system("PAUSE"); 16 } 17
6
Popis programu:
1
vyvoláme knihovnu i/o
2
main() zahájí program
3 4
5
deklarace proměnných
6
7 8
otevření souboru na zápis
9
načtení příjmení z klávesnice do prijmeni1, jmeno1, datumnarození1 10
načtení příjmení z klávesnice do prijmeni2, jmeno2, datumnarození2 načtení příjmení z klávesnice do prijmeni3, jmeno3, datumnarození3
12
13
zápis proměnných prijmeni1, jmeno1, datumnarození1 do souboru přes fd zápis proměnných prijmeni2, jmeno2, datumnarození2 do souboru přes fd zápis proměnných prijmeni3, jmeno3, datumnarození3 do souboru přes fd
14
15
uzavření souboru
16
zastavení programu
17
konec programu
Obr. č. 33: Výpis programu v C Zdroj: vlastní
25
Obr. č. 34: Obrazovka programu C po zadání hodnot Zdroj: vlastní
To, že jsme soubor vytvořili, si zkontrolujeme v textovém editoru:
Obr. č. 35: Výpis souboru narozeniny.txt v textovém editoru Zdroj: vlastní
26
Úkol č. 8 Upravte program P1 z úkolu č. 7 tak, aby využil cyklus for. Metodika řešení: I v tomto případě zaneseme počet klientů tzv. „natvrdo“, přiřazením n = 3. Vývojový diagram
Program v jazyku C:
Z 1
Deklarace proměnných
#include <stdio.h> main () { char prijmeni [30], int i, n; FILE *fd;
1
jmeno [30], datumnarozeni [30];
2
Otevřeme soubor narozeniny.txt na zápis „w“
fd=fopen("narozeniny.txt","w");
2
printf("Zadej prijmeni jmeno a udaje oddeluj znakem MEZERA \n"); 3
n=3
printf("Zadej datum narozeni ve tvaru RRRR-MM-DD \n"); printf("Zadavani kazdeho cloveka ukonci prikazem ENTER \n\n");
4
i=1;i<=3;+1
n=3;
3
for (i=1;i<=n;i++)
4
{ scanf("%s",prijmeni);
Načti prijmeni
Načti jmeno
scanf("%s",jmeno);
Načti datumnarozeni
scanf("%s",datumnarozeni);
fprintf(fd,"%s\n",prijmeni);
Tisk prijmeni[i]
fprintf(fd,"%s\n %s\n %s\n",prijmeni, jmeno, datumnarozeni);
fprintf(fd,"%s\n",jmeno); Tisk jmeno
Tisk datumnarozeni
fprintf(fd,"%s\n",datumnarozeni); }
i 5
Uzavření souboru (fd);
fclose(fd);
5
6
Zastavení programu
system("PAUSE");
6
7
K
}
7
Obr. č. 36: Vývojový diagram programu Zdroj: vlastní
27
Obr. č. 37: Výpis obrazovky v programu v C Zdroj: vlastní
Obr. č. 38: Obrazovka programu C po zadání hodnot Zdroj: vlastní
Obr. č. 39: Výpis souboru narozeniny.txt v textovém editoru Zdroj: vlastní
Samostatná práce studenta: Blok č. 3 nahraďte zadáním počtu klientů z klávesnice.
28
Úkol č. 9 Vypracujte program P2, který přečte data z programu P1 a vytiskne je na obrazovku. Metodika řešení: I v tomto případě postupujeme stejně jako v úkolu č. 7. Údaje ze souboru budeme načítat pro jednotlivé klienty (věty) do samostatných proměnných (příjmení, jméno, datum). Řešení: Vývojový diagram: Z 1
Deklarace proměnných 2
věta1
věta2
věta3
EOF
Otevři soubor narozeniny.txt na čtení fd
3
soubor věta1
proměnná
Načtení věty 1 z fd fd
prijmeni1
fd
fd
jmeno1
datum1
samostatné proměnné
4
Načtení věty 2 z fd
věta2
fd
prijmeni2
fd
fd
jmeno2
datum2
5 EOF
Načtení věty 3 z fd
věta3
fd
prijmeni3
fd
fd
jmeno3
datum3
6
Tisk věty 1
prijmeni1
tisk
jmeno1
tisk
datumi1
tisk
prijmeni2
tisk
7
Tisk věty 2
jmeno2
tisk
datumi2
tisk
prijmeni3
tisk
jmeno3
tisk
datumi3
tisk
8
Tisk věty 3 z fd 9
Uzavři soubor
K
10
Obr. č. 40: Vývojový diagram programu Zdroj: vlastní
29
Program v jazyku C: #include <stdio.h> main () {
Kotek
Jan
1997
Jan
1997
pracovnici.txt
1
char prijmeni1 [30], prijmeni2 [30], prijmeni3 [30]; char jmeno1 [30], jmeno2 [30], jmeno3 [30]; char datumnarozeni1 [30], datumnarozeni2 [30], datumnarozeni3 [30];
Kotek
fd
Kotek prijmeni1
FILE *fd; 2 fd=fopen("narozeniny.txt","r"); fscanf(fd,"%s %s %s",prijmeni1, jmeno1, datumnarozeni1); 3 fscanf(fd,"%s %s %s",prijmeni2, jmeno2, datumnarozeni2); 4 fscanf(fd,"%s %s %s",prijmeni3, jmeno3, datumnarozeni3); 5
Kotek pracovnici.txt
fd
Jan
printf("Vypis obsahu souboru narozeniny.txt:\n"); Jan printf("%s\n%s\n%s\n",prijmeni1, jmeno1, datumnarozeni1); 6 printf("%s\n%s\n%s\n",prijmeni2, jmeno2, datumnarozeni2); 7 printf("%s\n%s\n%s\n",prijmeni3, jmeno3, datumnarozeni3); 8
jmeno1
Kotek fclose(fd); 9
Jan
pracovnici.txt
system("PAUSE"); 10 fd
1997
} 1997 datumnarozeni1
Obr. č. 41: Výpis obrazovky v programu v C Zdroj: vlastní
Obr. č. 42: Obrazovka programu C po vypsání hodnot Zdroj: vlastní
30
1997
Úkol č. 10 Zadání: Upravte program P2 tak, aby využil cyklus for. Metodika řešení: V tomto řešení budeme opakovat postup z úkolu č. 8. Vývojový diagram:
Program v jazyku C:
Z
Deklarace proměnných
Otevřeme soubor narozeniny.txt na čtení „w“
n=3
vyčtu 3 věty
i=1;i<=n;+1
#include <stdio.h> main () { char prijmeni [30], jmeno [30], datumnarozeni [30]; int i, n; FILE *fd; fd=fopen("narozeniny.txt","r");
n=3;
for (i=1;i<=n;i++) {
Načti prijmeni
Načti jmeno fscanf(fd,"%s %s %s",prijmeni, jmeno, datumnarozeni); printf("%s\n%s\n%s\n",prijmeni, jmeno, datumnarozeni); Načti datumnarozeni
Načti datumnarozeni
i Uzavření souboru (fd);
Zastavení programu
K
}
fclose(fd);
system("PAUSE");
}
Obr. č. 43: Vývojový diagram programu Zdroj: vlastní
31
Obr. č. 44: Výpis obrazovky v programu v C Zdroj: vlastní
Obr. č. 45: Obrazovka programu C po vypsání hodnot Zdroj: vlastní
Úkol č. 11 Zadání: Spojte programy P1 a P2 do jednoho programu P3 a popište funkci celého programu. Metodika řešení: Z
V úkolu č. 11 vyřešíme zadání bez použití cyklu.
P1
V úkolu č. 12 vyřešíme problém s využitím cyklu.
P2
K
32
Program v jazyku C #include <stdio.h> main () { char prijmeni1 [30], prijmeni2 [30], prijmeni3 [30]; char jmeno1 [30], jmeno2 [30], jmeno3 [30]; char datumnarozeni1 [30], datumnarozeni2 [30], datumnarozeni3 [30]; FILE *fd; fd=fopen("narozeniny.txt","w");
/*naplnění souboru narozeniny.txt*/
scanf("%s %s %s",prijmeni1, jmeno1, datumnarozeni1); scanf("%s %s %s",prijmeni2, jmeno2, datumnarozeni2); scanf("%s %s %s",prijmeni3, jmeno3, datumnarozeni3);
P1
fprintf(fd,"%s\n %s\n %s\n",prijmeni1, jmeno1, datumnarozeni1); fprintf(fd,"%s\n %s\n %s\n",prijmeni2, jmeno2, datumnarozeni2); fprintf(fd,"%s\n %s\n %s\n",prijmeni3, jmeno3, datumnarozeni3); fclose(fd); system("PAUSE"); system ("CLS"); fd=fopen("narozeniny.txt","r");
/*vytištění souboru narozeniny.txt*/
fscanf(fd,"%s %s %s",prijmeni1, jmeno1, datumnarozeni1); fscanf(fd,"%s %s %s",prijmeni2, jmeno2, datumnarozeni2); fscanf(fd,"%s %s %s",prijmeni3, jmeno3, datumnarozeni3);
P2
printf("%s\n%s\n%s\n",prijmeni1, jmeno1, datumnarozeni1); printf("%s\n%s\n%s\n",prijmeni2, jmeno2, datumnarozeni2); printf("%s\n%s\n%s\n",prijmeni3, jmeno3, datumnarozeni3); fclose(fd); system("PAUSE"); }
Obr. č. 46: Výpis obrazovky v programu v C Zdroj: vlastní
33
Obr. č. 47: Výpis obrazovky v programu v C Zdroj: vlastní
Obr. č. 48: Obrazovka programu C po zadání hodnot Zdroj: vlastní
Obr. č. 49: Výpis souboru narozeniny.txt na obrazovku Zdroj: vlastní
Samostatná práce studenta: Nakreslete vývojový diagram.
34
Úkol č. 12 Upravte program P3 tak, aby využil cyklus for. Metodika řešení: Cílem tohoto úkolu je, aby student pochopil, jak využití cyklu významně zjednoduší zápis algoritmu a jak jej zprůhlední. Řešení: Vývojový diagram Z
Deklarace prijmeni, jmeno, datum narozeni, i, n, *fd Otevřeme soubor narozeniny.txt na zápis „w“ n=3
i=1;i<=n;i++
Načti prijmeni, jmeno, datumnarozeni Zapiš prijmeni, jmeno, datumnarozeni přes fd do narozeniny.txt
Program v jazyku C #include <stdio.h> main () { char prijmeni [30]; jmeno [30]; datumnarozeni [30]; int i,n; FILE *fd; fd=fopen("narozeniny.txt","w"); /*naplnění souboru*/
n=3;
for (i=1;i<=n;i++) {
scanf("%s %s %s",prijmeni, jmeno, datumnarozeni);
fprintf(fd,"%s\n %s\n %s\n",prijmeni, jmeno, datumnarozeni);
i } Uzavři narozeniny.txt Zastav program
CLS Otevřeme soubor narozeniny.txt na čtení „r“ n=3
Cyklus tisku obsahu souboru
Uzavři narozeniny.txt
Zastav
fclose(fd);
system("PAUSE");
system ("CLS");
fd=fopen("narozeniny.txt","r"); /*tisk obsahu souboru*/
n=3; for (i=1;i<=n;i++) { fscanf(fd,"%s %s %s",prijmeni, jmeno,datumnarozeni); printf("%s\n%s\n%s\n",prijmeni, jmeno,datumnarozeni); } fclose(fd);
system("PAUSE"); }
K
Obr. č. 50: Vývojový diagram programu Zdroj: vlastní
35
Obr. č. 51: Výpis programu v C Zdroj: vlastní
Obr. č. 52: Výpis souboru narozeniny.txt na obrazovku Zdroj: vlastní
Úkol č. 14 Nakreslete vývojový diagram, který vytvoří soubor třída.txt ve struktuře věty příjmení, jméno, věk, počet sourozenců pro každého žáka (položku) a následně tato zadaná data na obrazovku vypíše. Program pojmenujte P4. Ověřte jeho funkci textovým editorem. Metodický pokyn: 1
Nejprve deklarujeme proměnné. Příjmení a jméno může mít 30 znaků, i, n, věk, součet sourozenců jsou celá čísla.
2
Otevřeme soubor trida.txt na zápis.
3
P4 má evidovat data pro 3 žáky → n = 3.
4
36
V cyklu for načtu z klávesnice příjmení, jméno, věk a počet sourozenců do příslušné proměnné – přes scanf ( ) Lauko Pavel 22 1; Dufko Ivan 23 3; Pardova Jana 24 4.
7
V příkazu printf( ) vypíši hodnoty z těchto proměnných do souboru postupně v následujícím pořadí: příjmení, jméno, věk, počet sourozenců.
8
Soubor uzavřeme. Pozn.: V souboru máme zapsáno: Lauko Pavel 22 1 Dufko Ivan 23 3 Pardova Jana 24 4 7
Zastavíme program.
8
Soubor otevřeme na čtení.
9
V cyklu for načteme postupně první hodnotu souboru (příjmení) do proměnné „příjmení, druhou hodnotu do proměnné „jméno“ a třetí hodnotu do proměnné „věk“.
10
Příkazem printf ( ) vytiskneme, atd.
11
Po vyčtení všech dat soubor uzavřeme.
37
Vývojový diagram
Program v jazyku C #include <stdio.h> main () {
Z 1
Deklarace proměnných
char prijmeni [30];char jmeno [30]; int i,n,vek,pocetsourozencu; FILE *fd;
2
Otevřeme soubor trida.txt na zápis
1
fd=fopen("trida.txt","w"); 2
3
n=3;
n=3
3
4
i=1;i<=n;i++
for (i=1;i<=n;i++) {
Načtení hodnot z klávesnice do proměnné prijmeni, jmeno, vek, pocet sourozencu
4
scanf("%s %s %d %d",prijmeni, &pocetsourozencu);
jmeno,
&vek,
5
fprintf(fd,"%s\n%s\n%d\n%d\n",prijmeni, jmeno, vek, pocetsourozencu);
Zápis vytvořených proměnných přes fd do souboru trida.txt
5
}
i 6
Uzavření souboru (fd);
fclose(fd);
6
7
system("PAUSE"); system ("CLS");
Zastavení programu Smaž obrazovku 8
Otevřeme soubor trida.txt na čtení „r“
7
fd=fopen("trida.txt","r"); 8
for (i=1;i<=n;i++)
9
i=1;i<=n;+1 Načtení údajů ze souboru do 10 proměnných 11
Tisk údajů
{ fscanf(fd,"%s %s %d %d",prijmeni, jmeno, &vek, &pocetsourozencu); 10
printf("%s\n%s\n%d\n%d\n",prijmeni, jmeno, vek, pocetsourozencu); 11
}
i 12
Uzavření souboru Zastavení programu
fclose(fd); 12
13
system("PAUSE"); }
K
14
Obr. č. 53: Vývojový diagram programu Zdroj: vlastní
38
9
14
13
Obr. č. 54: Výpis programu v C Zdroj: vlastní
Obr. č. 55: Obrazovka programu C po zadání údajů Zdroj: vlastní
Obr. č. 56: Kontrolní výpis údajů v soubor pracov.txt textovým editorem Zdroj: vlastní
Úkol č. 15 Nakreslete vývojový diagram pro výpočet průměrného věku a průměrného počtu sourozenců ve třídě z programu P4 (z úkolu č. 14).
Metodický popis: Chceme-li vypočítat průměrný věk a průměrný počet sourozenců na žáka, musíme si vytvořit proměnné, do nichž budeme věk a počet sourozenců načítat. Nakonec jejich hodnoty podělíme počtem žáků.
39
věk = 0 počet = 0 Lauko Příjmení trida.txt
Pavel
18
jméno
věk
18
2
Dufko Ivan
počet Příjmení sourozenců
jméno
3
věk
2
Mala Jana
19
∑ Počet = 5
3
věk = 37 + 18
Počet = 5 + 2
Počet = počet + p1
věta 2
EOF
∑ věk = 55
∑ věk = 37
2+3
věta 1
2
p1
věk = 18 + 19
∑ Počet = 2
19
3
18
∑ Počet = počet + p1
18
počet sourozenců
p1
p1
věk = věk + p1 věk=0 věk = 18
19
∑ Počet = 7
věta 3
Obr. č. 57: Grafický popis řešení úkolu č. 14 Zdroj: vlastní
Ze souboru tedy vyčteme u prvního záznamu příjmení, vyčteme jméno. Když načteme věk do proměnné p1, připočteme p1 k proměnné věk. (v našem případě 0 + 18 = 18) Vyčteme počet sourozenců do p1 a tuto hodnotu přičteme k počet (v našem případě počet = 2). Toto opakujeme po větě 1 o i pro větu 2 a větu 3. Pro výpočet průměrného věku žáků podělíme výslednou proměnnou věku jejich počtem – n = 3. Pro výpočet průměrného počtu sourozenci podělíme výslednou proměnnou věku počtem žáků n = 3.
40
Vývojový diagram: Z
1
2
3
Deklarace proměnných Sour1 = sour1 + pocetsourozencu Otevřeme soubor trida.txt na zápis
i
n=3 suma = vek1/n i=1;i<=n;i++
suma2 = sour1/n Načtení hodnot z klávesnice do prijmení, jmeno, vek, pocet sourozencu
Zápis vytvořených proměnných přes fd do souboru trida.txt
Průměrný věk je prumer1
Průměrný počet sourozenců je prumer2
Uzavři soubor trida.txt
i Zastav program Uzavření souboru (fd); K
Zastavení programu
Otevřeme soubor trida.txt na čtení „r“
i=1;i<=n;+1
Načtení údajů ze souboru trida.txt do proměnných vek1=vek1+vek
Načti ze souboru trida.txt přes fd do pocetsourozencu
3
1
2
Pozn.: Pokud potřebujeme přerušit vývojový diagram, ukončíme čáru kroužkem, do něhož napíšeme číslo. Na jiném místě, kde má vývojový diagram pokračovat, začneme stejným číslem v kroužku.
Obr. č. 58: Vývojový diagram programu Zdroj: vlastní
41
Program v jazyku C #include <stdio.h> main () {
deklarace
i
vek
n
pocetsourozencu
int vek,i,n,pocetsourozencu; char jmeno[30], prijmeni[30]; double prumer1,vek1,sour1,prumer2; FILE *fd; vek1=0;
1 2 jmeno prumer1
3
……………….
vek1
fd
printf("Kolik studentu chcete zadat? ... "); scanf("%d",&n); fd=fopen("trida.txt","w"); for(i=0;i
prumer1=vek1/n; prumer2=sour1/n; printf("Prumerny vek je: %0.2lf\n",prumer1); printf("Prumerny pocet sourozencu je: %0.2lf\n",prumer2); fclose(fd); system("PAUSE");
42
sour1
29
prumer2
}
Obr. č. 59: Obrazovka programu C Zdroj: vlastní
43
Obr. č. 61: Obrazovka programu C po zadání údajů Zdroj: vlastní
Obr. č. 62: Obrazovka programu C po provedení výpočtů programem Zdroj: vlastní
1.5 Práce s EOF Úkol č. 16 Zadání: Vypracujte vývojový diagram a napište v jazyku C řešení následujícího úkolu: V úkolu č. 6 jsme vytvořili a naplnili soubor pracov.txt. Tento soubor obsahuje věty o struktuře: příjmení, jméno, mzda. Deklarujte proměnné následovně: char prijmeni [100][30]; char jmeno [100][30]; int mzda [100]; Vaším úkolem je otevřít tento soubor na čtení, zjistit, zda je naplněný a pokud ano vytisknout soubor (až po EOF). Využijte cyklus s while (!fscanf(fd)) a příkaz break v cyklu, pokud narazíme na EOF.
44
Metodika řešení: Nově použité pojmy: 1. fd==NULL Pokud není soubor vytvořený, je fd==NULL. Vytvořený soubor má fd ≠ NULL. Př.: if (fd==NULL) //jestliže soubor není vytvořen { printf("soubor neexistuje"); //vytiskni zprávu return; //ukonči práci }
2. RETURN v jednoduchém pojetí znamená ukončení prací. 3. !feof(fd) funkce feof( ) vrací nenulovou hodnotu, pokud soubor spojený s fd dosáhl svého konce. Jinak vrací nulu. Pokud je feof(fd) ≠ 0, dosáhl ukazatel na konec souboru. Znamená to, že existuje konec souboru.
Př.: while (!feof(fd)) //dokud nenarazíme na EOF realizujte. {
}
4. Příkaz break Pokud umístíme tento příkaz uvnitř cyklu, umožňuje ukončení cyklu v libovolném místě těla tohoto cyklu. Jakmile narazí program na break, je cyklus okamžitě ukončen a program pokračuje prvním příkazem následujícím za tímto cyklem. Př.: main ( ) { int i; for(i=1;i ≤ 100; i++) { printf("%d",i ); if (i==10) break; // pokud se i bude rovnat 10, ukončí se cyklus } }
Tento program vypisuje na obrazovku čísla 1, 2 až 10.
45
Pro řešení se nabízí využít cyklus while.
Vývojový diagram
Program v jazyku C
#include <stdio.h> main () { //deklarace int i,n; char prijmeni [100][30], jmeno [100][30]; int mzda [100]; FILE *fd;
Z
Deklarace proměnných
fd=fopen("pracov.txt","r"); //otevři soubor Otevřeme soubor trida.txt na čtení
fd== NULL?
ANO if(fd==NULL)
Soubor neexistuje
if (fd==NULL) //Pokud soubor neexistuje, fd==NULL { printf ("soubor neexistuje");return; } i=0;
i=0 K
while (!feof(fd)) je
EOF
není
while(!feof(fd))//dokud nenarazíš na EOF opakuj
{ fscanf(fd,"%s%s%d",prijmeni[i],jmeno[i],&mzda[i]);
Načti do pracov.txt prijmeni[1],jmeno[1], mzda[1]
Stojím na EOF?
ne
if (feof(fd))break; i=i+1; }
ano break Uzavři soubor
fclose(fd); //uzavři soubor //blok tisk
i=i+1
cyklus while
Tisk prijmeni[0], jmeno[0], mzda[0], prijmeni[1], jmeno[1], mzda[1], prijmeni[2], jmeno[2], mzda[2] ……..
Zastavení programu
K
Obr. č. 63: Vývojový diagram programu Zdroj: vlastní
46
printf("%s printf("%s printf("%s printf("%s printf("%s
%s %s %s %s %s
%d\n",prijmeni[0],jmeno[0],mzda[0]); %d\n",prijmeni[1],jmeno[1],mzda[1]); %d\n",prijmeni[2],jmeno[2],mzda[2]); %d\n",prijmeni[3],jmeno[3],mzda[3]); %d\n",prijmeni[4],jmeno[4],mzda[4]);
system("PAUSE");
}
Obr. č. 64: Výpis programu v C Zdroj: vlastní
Obr. č. 65: Výpis údajů ze souboru pracov.txt na obrazovku Zdroj: vlastní
Samostatná práce studenta: Upravte výstupní sestavu tak, aby byla data zarovnána do sloupců: Janal Mazal Palouk Janza Pavelec
Petr Jan Ivan Radim Radovan
12000 20000 15000 18000 17500
47
Úkol č. 17 Zadání: Máme vytvořený soubor pracov.txt – viz Úkol č. 16. Vaším úkolem je otevřít soubor pro čtení, zjistit zda je naplněný, a pokud ano, vytisknout soubor (až po EOF). Využijte cyklus do-while. Metodika řešení:
Z
Deklarace proměnných Otevřeme soubor pracov.txt na čtení i=0
je EOF
!feof(fd) cyklus while není EOF Soubor neexistuje
Načti ze souboru data do prijmeni[i],jmeno[i], mzda[i]
K
i=i+1
ne
Je EOF?
je EOF
Uzavři soubor i=0;i<=4;1 Tisk prijmeni[i], jmeno[i], mzda[i] i Zastavení programu
K
Obr. č. 66: Vývojový diagram programu Zdroj: vlastní
48
Janal
Petr
12000
Mazal
Jan
20000
EOF
pracov.txt
Janal fd
12000
Petr fd
fd
Jan
Mazal fd
fd
20000 fd
A Mazal
Janal
prijmeni[1]
prijmeni[0] ,
Petr
Jan
jmeno [0]
jmeno[1]
12000
prijmeni[0] ,
jmeno [0]
mzda[0]
20000 mzda[1]
mzda[0]
prijmeni[1]
jmeno[1]
B
mzda[1]
Obr. č. 67: Mechanismus čtení pracov.txt Zdroj: vlastní
Program v C: #include <stdio.h> main () { int i,n; char prijmeni [100][30]; char jmeno [100][30]; int mzda [100]; FILE *fd; fd=fopen("pracov.txt","r"); i=0; if(!feof(fd)) do { fscanf(fd,"%s%s%d",prijmeni[i],jmeno[i],&mzda[i]);
A
i=i+1; } while(!feof(fd)); fclose(fd); for(i=0;i<=4;i++) printf("%s%s%d\n",prijmeni[i],jmeno[i],mzda[i]); system("PAUSE");
B
}
49
Obr. č. 68: Výpis programu v C Zdroj: vlastní
Obr. č. 69: Výpis údajů ze souboru pracov.txt na obrazovku Zdroj: vlastní
50
Úkol č. 18 Vývojový diagram a program v jazyku C z úkolu č. 16 upravte tak, aby samostatného cyklu for pro tisk příjmení, jméno a mzdy nebylo vůbec potřeba. Metodika řešení: Řešení tohoto úkolu je velmi jednoduché. Využijeme příkaz printf – viz následující. Program v C: #include <stdio.h> main () { int i,n; 1 char prijmeni [100][30]; char jmeno [100][30]; int mzda [100]; FILE *fd; fd=fopen("pracov.txt","r"); 2 i=0; 3 while(!feof(fd)) //dokud nenarazíš na eof opakuj 4 { 5 fscanf(fd,"%s%s%d",prijmeni[i],jmeno[i],&mzda[i]); 6 if(!feof(fd)) printf("%s %s %d\n",prijmeni[i],jmeno[i],mzda[i]); i=i+1; 8 } Pozn.: Soubor pracov.txt je textový soubor. Na fclose(fd); 9 posledním řádku proto může být jen ENTER a system("PAUSE"); 10 nejsou tam žádná data. Program by nic nenačetl, } 11 zůstala by poslední data v proměnných, a proto by
7
program realizoval znovu výpis posledních dat. Narazí-li 6 na EOF, projde na konec cyklu a tisk již nevyvolá.
Obr. č. 70: Výpis programu v C Zdroj: vlastní
Obr. č. 71: Výpis programu v C Zdroj: vlastní
51
Úkol č. 19 Zadání: Máte soubor pracov.txt o zadané struktuře. Vypracujte vývojový diagram a program v C, který zjistí, zda je soubor pracov.txt prázdný nebo naplněný. Pokud nejde o prázdný soubor, v následující části programu jej vyčteme. Metodický pokyn: Pokud je soubor pracov.txt prázdný, pokračujeme prvním načtením do pomocné proměnné CH CH=fgetc(fd) EOF. Pozor – tímto vyčtením první položky ze souboru pracov.txt jsme se posunuli na položku druhou, a proto musíme soubor znovu otevřít, abychom se vrátili na položku č. 1. Touto operací zjišťujeme, zda se nepokoušíme číst prázdný soubor. Vývojový diagram
Program v jazyku C:
Z
#include <stdio.h> main () { int i,n; char prijmeni [100][30]; char jmeno [100][30]; int mzda [100]; char ch; FILE *fd;
Deklarace Otevřeme soubor pracov.txt na čtení
Nastavení počítadla i =0 Načtení prvního údaje ze souboru do proměnné „ch“ ano ch ==EOF? ne
Soubor je prázdný
Soubor není prázdný
Otevři znovu soubor pracov.txt na čtení i=1;i<=4;i+1 Načti z fd doprijmeni[i], jmeno[i], mzda[i]
fd=fopen("pracov.txt","r"); i=0; ch=fgetc(fd); if(ch==EOF) { printf("Soubor je prazdny\n"); } else {printf("Soubor neni prazdny\n"); fd=fopen("pracov.txt","r"); //nutno znovu otevřít soubor, abychom se vrátili na začátek souboru for(i=0;i<=4;i++) { fscanf(fd,"%s%s%d",prijmeni[i],jmeno[i],&mzda[i]); printf("%s%s%d\n",prijmeni[i],jmeno[i],mzda[i]); } }
Vytiskni prijmeni[i], jmeno[i], mzda[i]
fclose(fd); i Uzavření souboru Zastavení programu K
Obr. č. 72: Vývojový diagram programu Zdroj: vlastní
52
system("PAUSE"); }
Obr. č. 73: Výpis programu v C Zdroj: vlastní
Obr. č. 74: Výpis údajů ze souboru pracov.txt Zdroj: vlastní
Úkol č. 20 Aplikujte tento program na soubor pracov1.txt vytvořený v Úkolu č. 3 (tam jsme vytvořili prázdný soubor), tak abyste ověřili, zda program funguje i pro jiný soubor (má ukázat, že soubor je prázdný). K řešení v jazyku C nakreslete vývojový diagram. Program v jazyku C: #include <stdio.h> main () { int i,n; char prijmeni [100][30], char jmeno [100][30]; int mzda [100]; char ch; FILE *fd; fd=fopen("pracov1.txt","r"); i=0; ch=fgetc(fd); if(ch==EOF) { printf("Soubor je prazdny\n"); } Obr. č. 75: Výpis programu v C else Zdroj: vlastní {printf("Soubor neni prazdny\n"); for(i=0;i<=4;i++) { fscanf(fd,"%s%s%d",prijmeni[i],jmeno[i],&mzda[i]); printf("%s%s%d\n",prijmeni[i],jmeno[i],mzda[i]); } } fclose(fd); system("PAUSE"); }
53
Obr. č. 76: Výpis programu v C Zdroj: vlastní
Nakreslete vývojový diagram
54
Úkol č. 21 Zadání: Realizujte úkol č. 19 s využitím cyklu while. Metodický pokyn: V tomto případě vycházíme z úkolu č. 19 s využitím cyklu while. Po počátečním ověření, zda soubor není prázdný, použijeme konstrukci if((fd=fopen("pracov.txt", "r"))=NULL return; která při načtení souboru zjistí, že fd je prázdná a program ukončí.
Vývojový diagram
Program v jazyku C
Z
Deklarace proměnných
#include <stdio.h> main() { char prijmeni[100][30]; char jmeno[100][30]; int mzda[100]; int i,n; FILE *fd;
i=0
Otevři soubor pracov.txt na čtení
EOF?
fd==NULL ANO
NE
EOF?
i=0; if((fd=fopen("pracov.txt","r"))==NULL) return; //pokud je soubor prázdný, ukončí práci
return K
ANO
while(!feof(fd)) //cteni souboru {
NE fcanf(fd,"%s%s%d",prijmeni[i],jmeno[i],& mzda[i]);
Načti data
EOF
ANO brake
if (feof(fd)) break; //pokud fd stojí na EOF, přejdi na konec cyklu
NE i=i+1
i=i+1; } fclose(fd);
Zavři soubor
i=n;
i=n
for (i = 0;i < n; i++) {
i=1; n; +1 Vypiš data
printf("%s%s%d",prijmeni[i],jmeno[i], &mzda[i]);
i
}
i Zastavení programu
K
system("PAUSE");
//ceka stisk klavesy
}
Obr. č. 77: Vývojový diagram programu Zdroj: vlastní
55
Obr. č. 78: Výpis programu v C Zdroj: vlastní
Obr. č. 79: Výpis údajů ze souboru pracov.txt Zdroj: vlastní
56
Úkol č. 22 Zadání: Vypracujte vývojový diagram na evidenci termínů narozenin blízkých a spolužáků. Počet účastníků databáze nesmí být větší než 100. Program bude mít MENU z – zadání dat, c – čtení dat. Metodický pokyn: V tomto příkladě vytváříme MENU, které dovolí operátorovi volit jednu ze dvou variant – zápis (vytvoření databáze) nebo čtení databáze. Rozhodování v MENU děláme podle proměnné POVEL. Protože příkaz getchar činí často potíže, uložíme si v tomto případě volbu (povel) do nultého prvku pole povel [2] – typ char. Vývojový diagram:
Z 1
Deklarace proměnných
2
n
Zadej počet položek n=? 3
MENU Z – zadání dat C – čtení dat 4
Načti zvolenou variantu do „povel“
5a
5b
c
5
Povel = ? z
6
Otevři soubor svatky.txt na čtení
Otevři soubor svatky.txt na zápis 7
i = 1, n, i++
i = 1, n, i++
Přečti Příjmení [i]; Jméno
16
[i]; Datum narození [i] ze souboru pracov.txt
9
Zadej Příjmení [i];
10
Zadej Jméno [i];
11
Zadej Datum narození [i];
12
Zapiš Příjmení [i]; Jméno [i];
Vytiskni Příjmení [i]; Jméno [i]; Datum narození [i]
Datum narození [i] do souboru pracov.txt
i
15
8
Pořadí pracovníka [i];
14
13
i
Zavři soubor svatky.txt Vytiskni „Konec“ Zastav program K
17
18
19
20
Samostatná práce studenta:
21
Podrobněji rozpracuj bloky 12 a 17.
22
Obr. č. 80: Vývojový diagram programu Zdroj: vlastní
57
Program v jazyku C: Varianta A #include <stdio.h> main () { int n,i;1 char prijmeni [100][30]; char jmeno [100][30]; char datum_narozeni [100][30]; char povel[2]; FILE *fd; printf("Zadej pocet polozek:");2 scanf("%d",&n); printf("Chcete zapisovat ...Z\n");3 printf("Chcete tisknout... T\n");
scanf("%s",povel);4 //načtení povelu T(čtení) nebo Z (zápis)
if(povel[0]=='Z')5a { fd=fopen("svatky.txt","w"); 6 for(i=1;i<=n;i++) 7 { printf("zadej pracovnika %d\n",i); 8 scanf("%s",prijmeni[i]); 9 scanf("%s",jmeno[i]); 10 scanf("%s",datum_narozeni[i]); 11 fprintf(fd,"%s %s %s",prijmeni[i],jmeno[i], 12 datum_narozeni[i]); } 13 fclose(fd); 19 } 5b if(povel[0]=='T') { fd=fopen("svatky.txt","r"); 14 for(i=1;i<=n;i++) 15 { fscanf(fd,"%s %s %s",prijmeni[i],jmeno[i],datum_narozeni[i]); 16 printf("%s %s %s\n",prijmeni[i],jmeno[i],datum_narozeni[i]); 17 } 18 fclose(fd); 19 } 20 printf("Konec"); 21 system("PAUSE");
} 22
58
Výpis programu a obrazovky jsou v následujícím textu.
Obr. č. 81: Výpis programu v C Zdroj: vlastní
Obr. č. 82: Obrazovka v programu C po zadání údajů Zdroj: vlastní
Obr. č. 83: Obrazovka v programu C se zadáním údajů pro zobrazení dat ze souboru Zdroj: vlastní
59
Obr. č. 84: Výpis souboru svatky.txt na obrazovku Zdroj: vlastní
Výpis souboru v textovém editoru:
věta 1
věta 2
věta 3
Obr. č. 85: Výpis souboru svatky.txt v textovém editoru Zdroj: vlastní
Varianta B V této variantě si ukážeme, že getch lze pro načtení volby použít také. #include <stdio.h> main () { int n,i; char prijmeni [100][30]; char jmeno [100][30]; char datum_narozeni [100][30]; char p; FILE *fd; printf("Zadej pocet polozek:"); scanf("%d",&n); printf("Chcete zapisovat ...Z\n"); printf("Chcete tisknout... T\n"); p=getch(); if(p=='Z') { fd=fopen("svatky.txt","w"); for(i=1;i<=n;i++) { printf("zadej pracovnika %d\n",i); scanf("%s",prijmeni[i]); scanf("%s",jmeno[i]); scanf("%s",datum_narozeni[i]); fprintf(fd,"%s %s %s ",prijmeni[i],jmeno[i],datum_narozeni[i]); } fclose(fd); } if(p=='T') { fd=fopen("svatky.txt","r"); for(i=1;i<=n;i++) { fscanf(fd,"%s %s %s",prijmeni[i],jmeno[i],datum_narozeni[i]); printf("%s %s %s\n",prijmeni[i],jmeno[i],datum_narozeni[i]); } fclose(fd); } 1
60
printf("Konec"); system("PAUSE");
1
}
Velkou nevýhodou tohoto programu je, že při režimu T – stisknout, musíme v úvodu uvést, kolik vět soubor obsahuje. Potřebujeme program, který načte a zapíše do databáze takový počet vět (pracovníků), jaký vyžadujeme. Následně v režimu T vytiskneme celý soubor (větu po větě, až po EOF). V dalším textu si ještě procvičíme vytváření a čtení jednoduché databáze.
1.6 Tvorba databází Úkol č. 23 Zadání: Vytvořte personální databázi pracovníků útvaru. Počet pracovníků je zadán a nepřekročí 100. V této databázi bude o každém pracovníkovi uloženo: 1. 2. 3. 4. 5. 6.
Příjmení Jméno Bydliště – město Bydliště – ulice Bydliště – číslo domu Datum narození
Program Vám nabídne: a) vytvoření databáze, b) čtení databáze. Data uložte do textového souboru personalistika.txt Metodický pokyn: Tato úloha procvičí dovednosti, které jsme získali v předešlém studiu: - práce s MENU, - práce se souborem. Jedná se o standardní software, který využije každý ekonom, manažer, účetní nebo personalista ve své práci. Soubor personalistika.txt bude mít strukturu: věta 1: Příjmení [0] jméno [0] město [0] ulice[0] číslo domu [0]
Datum narození Datum narození Datum narození - den [0] - měsíc [0] – rok [0]
personalistika.txt Příjmení [1] jméno [1] město [1] ulice[1] číslo domu [1]
Datum narození Datum narození Datum narození - den [1] - měsíc [1] – rok [1]
Příjmení [2] jméno [2] město [2] ulice[2] číslo domu [2]
Datum narození Datum narození Datum narození - den [2] - měsíc [2] – rok [2]
61
Tuto strukturu lze také zobrazit následujícím grafem (jiné zobrazení této databáze): Příjmení [0]
Pracovník [0]
Personalistika.txt
Jméno [0] Pracovník [1]
Bydliště - město [0] Bydliště – ulice [0]
Pracovník [2]
Bydliště – číslo domu [0]
Pracovník [99]
Datum narození den [0] Datum narození měsíc [0] Datum narození rok [0]
Řešení:
Z
Vývojový diagram Deklarace
Zadat počet položek
MENU: Zadat data o pracovníkovi …….. Z Tisknout data o pracovníkovi ….. T
Načtení
Povel = Z
Otevřít soubor personalistika.txt na zápis
Řešíme "w"
i=1;i<=n;i++)
Zadat data Příjmení [i] Jméno [i] Bydliště - město [i] Bydliště – ulice [i] Bydliště – číslo domu [i] Datum narození den [i] Datum narození měsíc [i] Datum narození rok [i]
volby
Povel
do
Povel = T
Otevři soubor personalistika.tx. na čtení
i=1;i<=n;i++) Načtení dat o pracovníkovi z personalistika.txt přes fd do proměnných Vytiskni proměnné
i
Zavři personalistika.txt Načtení dat přes fd do personalistika.txt
i
Obr. č. 86: Vývojový diagram programu Zdroj: vlastní
62
PAUSE
„Konec“
Z
soubor
Řešíme "r"
Zápis v jazyku C: #include <stdio.h> main () { int i,n; int ch; /*udaje ze souboru */ char prijmeni[100][30]; char jmeno[100][30]; char mesto[100][30]; char ulice[100][30]; char cislo[100][20]; char datum[100][11]; //datum bereme jako řetězec
/*ukazka dat*/ /*Novak Jan Brno Veveri 145/c 18.9.1992*/ FILE *fd; i=0; printf("zadejte pocet pracovniku:"); scanf ("%d",&n); printf("MENU Z zapis T tisk:\n"); printf("zadejte prvni pismeno:\n"); ch=getch();
if(ch=='Z') { fd=fopen("personalistika.txt","w"); //otevření pro zápis údajů o pracovnících for (i=0;i
}
2
1
if(ch=='T') { fd=fopen("personalistika.txt","r"); //otevření pro čtení printf("data ze souboru\n"); 3
63
2
1
3
for (i=0;i
Obr. č. 87: Výpis programu v C Zdroj: vlastní
64
Obr. č. 88: Výpis programu v C Zdroj: vlastní
Obr. č. 89: Výpis programu v C Zdroj: vlastní
Obr. č. 90: Výpis databáze v textovém editoru Zdroj: vlastní
Obr. č. 91: Výpis programu v C Zdroj: vlastní
65
Úkol č. 24 Zadání: Vypracujte vývojový diagram a přepište do jazyka C následující zadání: Máme vytvořit databázi pracovníků, do níž můžeme zapsat (v MENU …..Z) nebo z ní číst – (v MENU ….T). Struktura věty souboru personalistika.txt je: Příjmení, jméno, bydliště-město, bydliště - ulice, bydliště - číslo domu, datum narození. Program má odstranit všechny nedostatky řešení úkolu č. 23: a) při zadávání údajů bude čtení dat z klávesnice ukončen po dotazu na pokračování, b) při čtení vět proběhne čtení souboru automaticky až po EOF.
Metodický pokyn: Vycházíme z příkladu č. 23. V tomto případě provedeme načtení dat ze souboru personalistika.txt pomocí cyklu do-while s tím, že pro rozhodování připravíme speciální menu a proměnnou pokračovat typu int. scanf ("%d",pokracovat); while(pokracovat==1);
do {
načti pracovníka }
Načtení dat ze souboru personalistika.txt realizuje sekvence příkazů B: while(!eof(fd)); { Načtení dat ze souboru personalistika.txt přes fd do proměnných prijmeni[i],jmeno[i] ….. Ukončení cyklu v případě, že se narazí na EOF (if (feof(fd)break;)
66
Vývojový diagram:
Z Deklarace proměnných MENU Z – zadání dat T – tisk Načti CH
A CH = Z
CH
Otevři soubor personalistika.txt na zápis načti z klávesnice
CH = T
B
prijmeni [i] jmeno [i] mesto [i] Otevři soubor personalistika.txt na čtení
ulice [i] cislo [i] datum [i] Zápis do souboru
prijmeni [i] jmeno [i] mesto [i] ulice [i] cislo [i] datum [i]
EOF
stojím na EOF
Načtení z fd do proměnných prijmeni [i], jmeno [i]., mesto [i] ulice [i], cislo [i], datum [i]
pokračovat = 1 konec = 0 CH
EOF CH == 1 NE
Zavři soubor
ANO vystup z cyklu
Tisk prijmeni [i], jmeno [i]., mesto [i], ulice [i], cislo [i], datum [i]
i=i+1
Data zapsaná do souboru
Zavři soubor zastav
K Obr. č. 92: Vývojový diagram programu Zdroj: vlastní
67
Program v jazyku C: #include <stdio.h> main () { int i,n; int ch,pokracovat; /*udaje ze souboru */ char prijmeni[100][30]; char jmeno[100][30]; char mesto[100][30]; char ulice[100][30]; char cislo[100][20]; char datum[100][11];
/*ukazka dat*/ /* Novak Jan Brno Veveri 145/c 18.9.1992 */ FILE *fd; i=0; printf("MENU Z zapis T tisk:\n"); printf("zadejte prvni pismeno:\n"); ch=getch();
if(ch=='Z') { fd=fopen("personalistika.txt","w"); //otevreni pro cteni
A
do { printf("zadejte printf("zadejte printf("zadejte printf("zadejte printf("zadejte printf("zadejte
prijmeni:");scanf ("%s",prijmeni[i]); jmeno:");scanf ("%s",jmeno[i]); mesto:");scanf ("%s",mesto[i]); ulici:");scanf ("%s",ulice[i]); cislo domu:");scanf ("%s",cislo[i]); datum [den.mesic.rok]:");scanf ("%s",datum[i]);
fprintf(fd,"%s ",prijmeni[i]); fprintf(fd,"%s ",jmeno[i]); fprintf(fd,"%s ",mesto[i]); fprintf(fd,"%s ",ulice[i]); fprintf(fd,"%s ",cislo[i]); fprintf(fd,"%s\n",datum[i]); i++; printf("pokracovat ano=1 / ne=0:"); scanf ("%d",&pokracovat); } while(pokracovat==1);
fclose(fd);//uzavreni souboru
}
printf("data zapsana do souboru\n"); //Zapis if(ch=='T') B { fd=fopen("personalistika.txt","r"); //otevreni pro cteni printf("data ze souboru\n"); while(!feof(fd)) {
1
fscanf(fd,"%s%s%s%s%s%s",prijmeni[i],jmeno[i],mesto[i],ulice[i],cislo[i],datum[i]); 2 //cteni dalsich radku souboru
68
2
1
if ( feof(fd) ) break; printf("%6d ",i+1); printf("%-15s",prijmeni[i]); printf("%-15s",jmeno[i]); printf("%-10s",mesto[i]); printf("%-10s",ulice[i]); printf("%-8s",cislo[i]); printf("%-10s\n",datum[i]); i++; } fclose(fd);//uzavreni souboru } system("PAUSE");
} jj
Obr. č. 93: Výpis programu v C++ Zdroj: vlastní
69
Úkol č. 25 Nakreslete vývojový diagram a program v jazyku C z úlohy č. 24 tak, aby čtení vět z klávesnice bylo ukončeno po stisknutí klávesy ENTER. Metodický pokyn: V tomto případě použijeme malý trik. Pokud při zadávání příjmení zadáme do nulté pozice nulu v bloku 1 v následujícím bloku testujeme tuto pozici na nulu v příkazu if (prijmeni[i] [0] == brak; vyskočíme z cyklu, soubor personalistika.txt se zavře a program se zastaví. Podobně také v 2 odcházíme z cyklu příkazem if (feof (fd)) break;
70
Vývojový diagram:
Z Deklarace proměnných i=0 MENU Z – zadání dat T – tisk Načti CH ANO
zápis
CH = Z
Otevři soubor personalistika.txt na zápis 1 Zadej prijmeni [i]
Otevři soubor personalistika.txt na čtení
== "0" vystup z cyklu Prijmeni [i] [0]
načti prijmeni [i] načti jmeno [i] načti mesto [i] načti ulice [i] načti cislo [i] načti datum [i]
zapiš prijmeni [i], jmeno [i] mesto [i], ulice [i], cislo [i] datum [i] do souboru personalistika.txt
stojím na EOF
EOF prázdný soubor nestojím na EOF
i=i+1
Načtení z fd do proměnných prijmeni [i], jmeno [i]., mesto [i] ulice [i], cislo [i], datum [i]
while (1)
ANO vystup z cyklu
EOF Zavři soubor
NE tisk
zastav
K
Tisk: prijmeni [i], jmeno [i] mesto [i], ulice [i], cislo [i] datum [i]
i=i+1
Obr. č. 94: Vývojový diagram programu Zdroj: vlastní
71
Program v jazyku C: #include <stdio.h> main () { int i,n; int ch,pokracovat; /*udaje ze souboru */ char prijmeni[100][30]; char jmeno[100][30]; char mesto[100][30]; char ulice[100][30]; char cislo[100][20]; char datum[100][11];
/*ukazka dat*/ /*Novak Jan Brno Veveri 145/c 18.9.1992*/ FILE *fd; i=0; printf("MENU Z zapis T tisk:\n"); printf("zadejte prvni pismeno:\n"); ch=getch();
if(ch=='Z') { fd=fopen("personalistika.txt","w"); //otevreni pro cteni do { printf("zadejte prijmeni:");scanf ("%s",prijmeni[i]); //pokud nezadame prijmeni, cyklus se ukonci if (prijmeni[i][0]=='0') break; //pokud se první písmeno prijmeni = nule, brake //naplnení proměnných z klávesnice printf("zadejte jmeno:");scanf ("%s",jmeno[i]); printf("zadejte mesto:");scanf ("%s",mesto[i]); printf("zadejte ulici:");scanf ("%s",ulice[i]); printf("zadejte cislo domu:");scanf ("%s",cislo[i]); printf("zadejte datum [den.mesic.rok]:");scanf ("%s",datum[i]); //naplnení proměnných do souboru personalistika.txt přes fd fprintf(fd,"%s ",prijmeni[i]); fprintf(fd,"%s ",jmeno[i]); fprintf(fd,"%s ",mesto[i]); fprintf(fd,"%s ",ulice[i]); fprintf(fd,"%s ",cislo[i]); fprintf(fd,"%s\n",datum[i]); i++; } while(1); fclose(fd);//uzavreni souboru printf("data zapsana do souboru\n"); //Zapis
}
if(ch=='T') { fd=fopen("personalistika.txt","r"); //otevreni pro cteni printf("data ze souboru\n"); while(!feof(fd)) 3 2
72
1
3
2
{
1
fscanf(fd,"%s%s%s%s%s%s",prijmeni[i],jmeno[i],mesto[i],ulice[i],cislo[i],datum [i]);//cteni dalsich raku souboru if ( feof(fd) ) break; printf("%6d ",i+1); printf("%-15s",prijmeni[i]); printf("%-15s",jmeno[i]); printf("%-10s",mesto[i]); printf("%-10s",ulice[i]); printf("%-8s",cislo[i]); printf("%-10s\n",datum[i]); i++; } fclose(fd);//uzavreni souboru } system("PAUSE"); }
1.7 Práce s parametrem „r+“ V následujícím textu se budeme zabývat tím, jak do vytvořeného souboru dopsat za poslední větu další data (věty). Máme například databázi narozenin přátel prijmeni
jmeno
svatky.txt
datum narození
prijmeni
věta 1
jmeno
datum narození
EOF
věta 2
a ukázala se potřeba zapsat za poslední větu další dva přátele. Pro takový případ můžeme soubor svatky.txt otevřít s parametrem (r+), který lze použít následovně: 1. 2. 3. 4.
Otevřeme soubor svatky.txt s parametrem r+. Postupně čteme všechny věty až po EOF. Zapíšeme nové věty. Soubor uzavřeme.
Použití r+ parametru ukazuje následující úkol č. 26. Jak tuto konstrukci využijeme v praxi? Máme například soubor personalistika.txt a máme v něm evidováno 5 pracovníků malého podniku. Podnik nyní přijme dalších 7 pracovníků a soubor personalistika.txt potřebuje tyto pracovníky doplnit. K řešení této úlohy využíváme parametr „r+“ pro práci se soubory. V takovém případě nejprve přečteme 5 stávajících vět (fd se posune od první věty za 5 větu). Následuje zápis dalších 7 vět přes fd. Nově zapsané položky
Stávající položky
Kotek
Malík
Fisko
Karda
Blaza
EOF
personalistika.txt
73
Úkol č. 26 Zadání: Soubor plat.txt, který vznikl v úkolu č. 2, nejprve přečtěte a následně do něj zapište 3 nové položky. Zobrazte v textovém editoru. Metodický pokyn a vývojový diagram: Z příkladu č. 2 máme vytvořený soubor plat.txt s jednou konkrétní hodnotou 14500. 14500
EOF
plat.txt
Tento soubor lze přečíst v textovém editoru:
Obr. č. 95: Data uložená v souboru plat.txt Zdroj: vlastní
r+ znamená, že musíme přečíst všechny položky souboru plat.txt a teprve potom můžeme připisovat nová data. Konec souboru je označen EOF. Pokud máme dopsat do souboru další tři položky, bude mít po skončení práce následující strukturu: 14500
EOF
první položka
druhá položka
plat.txt
Ukazatel souboru upozorňuje na začátek souboru. Postup vidíme na následujícím vývojovém diagramu. Ve 4 a 5 načteme první položku do proměnné p1 a p1 vytiskneme na obrazovku. Ukazovátko se posune na druhou položku. Protože máme nastavený režim r+ , máme právo do druhé položky zapisovat. To provedeme načtením hodnoty z klávesnice (v našem případě 44 000) do p1 a p1 zapíšeme p1 6 (7 7a 7b 7c ). přes fd do plat.txt na druhou pozici Nyní má soubor plat.txt následující strukturu: 14 500
44 000
EOF
Plat.txt
Načtení další položky činíme podobně v
8
8a
9
9a
9b
9c
Nyní má soubor následující strukturu: 14 500
44 000
55 550
Načtení další položky činíme podobně v Ve 74
12
uzavřeme soubor a zrušíme.
EOF 10 10a
11
11a
11b 11c
Tento soubor bude mít následující strukturu: 14 500
44 000
55 550
80 500
14500
1
EOF
EOF
plat.txt
Z
3c 2
3b
7c
14500
44000
EOF
14500
44 000
55550
EOF
14500
44000
55550
80500
9c
Deklarace proměnných 3
Otevři soubor plat.txt na r+
EOF
11c
3a
14500
EOF
fd
4a 4
Načteme první (jedinou) Položku do p1
14500
5
p1
7b
Vytiskni p1
44000 p1
7a
Zapiš p1 do plat.txt 8
8a
Načti další položku do p1
55550 p1
9
9a
Zapiš p1 do plat.txt 10
80 500
11b
6a
Načti další položku do p1 7
55 550
9b
14500 6
44 000
5a
10a
Načti další položku do p1
80500
11
p1 11a
Zapiš p1 do plat.txt 12
Obsah nově vytvořeného souboru
Uzavři soubor plat.txt
14500 13
44 000
55550
80500
EOF
plat.txt
Zastav obrazovku
Z
Obr. č. 96: Vývojový diagram programu Zdroj: vlastní
75
Program v jazyku C: #include <stdio.h> main () { int p1; 2 FILE *fd; fd=fopen("plat.txt","r+"); 3 fscanf(fd,"%d",&p1); 4 printf("%d\n",p1); 5
Načtení první položky do souboru p1, posun fd.
//jsme na konci souboru scanf("%d",&p1); 6 fprintf(fd,"\n%d\n",p1); 7
Zápis druhé položky do souboru p1, posun fd.
scanf("%d",&p1); 8 fprintf(fd,"%d\n",p1); 9
Zápis třetí položky do souboru p1, posun fd.
scanf("%d",&p1); 11 fprintf(fd,"%d\n",p1); 11
Zápis čtvrté položky do souboru p1, posun fd.
fclose(fd); //zruseni fd system("PAUSE"); 13
}
76
12
Uzavření souboru plat.txt
Obr. č. 97: Původní soubor plat.txt Zdroj: vlastní
Obr. č. 98: Obrazovka programu C Zdroj: vlastní
Obr. č. 99: Obrazovka programu C po zadání první hodnoty Zdroj: vlastní
Obr. č. 100: Obrazovka programu C po zadání druhé hodnoty Zdroj: vlastní
Obr. č. 101: Obrazovka programu v C po zadání všech hodnot Zdroj: vlastní
Obr. č. 102: Výpis výsledku v textovém editoru Zdroj: vlastní
77
1.8 Vytvoření záložního souboru V praxi často potřebujeme vytvořit ze souboru zálohy. Originál takto přepisujeme do kopie. V originálním souboru čteme jednu položku po druhé a postupně ji zapisujeme do kopie. Originál je tedy zdrojový soubor, kopie je záložní soubor. Nezapomeňte, že než začnete přepisovat ze zdrojového souboru data do záložního souboru, musíte mít záložní soubor vytvořený a otevřený pro zápis. Dovednost přepisu základního souboru do zálohy budete potřebovat při operativních vyhledávání v souboru, opravách položek, setříďování souborů atd.
Úkol č. 27 V úkolu č. 26 jste vytvořili soubor plat.txt. Tento soubor chceme zálohovat jako soubor plat1.txt. Nakreslete vývojový diagram a přepište do jazyka C. Metodický pokyn: Našim úkolem je postupně přečíst názvy v původním souboru plat.txt a přes pomocnou proměnnou p1 je přepsat do nového souboru plat1.txt. plat.txt 14500
14500
zdrojový soubor 44000
55550
80500
EOF
plat.txt 44000
fopen("plat.txt", "r");
55550
80500
EOF
44000
fd1
fd1 14500
zdrojový soubor
14500
scant("%s", p);
44000
p
p 14500
14500
44000
printf(fd2, "%s", p);
fd2 plat1.txt
kopie
14500
EOF
Kopírování první položky
plat.txt 14500
fd2 plat1.txt
55550
80500
kopie EOF
Kopírování druhé položky
zdrojový soubor 44000
44000
EOF
plat.txt 14500
zdrojový soubor 44000
55550
80500
80500
55550
fd1
fd1
80500
55550
p
p 55550
80500
fd2
fd2 plat1.txt 14500
kopie 44000
EOF
55550
EOF
plat1.txt 14500
kopie 44000
55550
80500
EOF
close
Kopírování třetí položky
78
Kopírování čtvrté položky a uzavření zdrojového souboru i kopie
Vývojový diagram: Z Deklarace proměnných Otevři plat.txt na čtení
Existuje plat.txt?
NE fd1==NULL
K ANO fd1≠ NULL
Otevři soubor plat1.txt na zápis
EOF plat.txt?
stojím na EOF
nestojím na EOF
Přečtení z plat.txt do proměnné mzda
EOF fd1?
Zápis mzda do fd2
ANO
Zavři fd1
Zavři fd1 Kopírování ukončeno
zastav
K Obr. č. 103: Vývojový diagram programu č. 27 Zdroj: vlastní
79
Program v jazyku C: #include <stdio.h> main() { FILE *fd1,*fd2; int mzda; //vstupní soubor if((fd1=fopen("plat.txt","r"))==NULL) return; //výstupní soubor fd2=fopen("plat1.txt","w"); //cteni dat v cyklu dokud neni konec souboru while(!feof(fd1)) /* vypis souboru */ { fscanf (fd1,"%d",&mzda); if ( feof(fd1) ) break; fprintf(fd2,"%d ",mzda); } //uzavreni souboru fclose(fd1); fclose(fd2); printf("kopirovani ukonceno \n "); system("PAUSE"); }
Obr. č. 104: Výpis programu v jazyku C++ Zdroj: vlastní
Obr. č. 105: Výsledná obrazovka programu Zdroj: vlastní
80
2 Šifrování a kryptografie Abychom se mohli zabývat zabezpečením proti neoprávněnému čtení, případně zásahům při přenosu informace, nahlédněme spolu do krátké historie z této oblasti. Utajování obsahu zpráv provází lidstvo od jeho samého počátku. Využití šifrování mnohokrát ovlivnilo běh dějin.
2.1 Cílové znalosti a dovednosti Čtenář si osvojí způsoby zabezpečení přenosu dat proti neoprávněnému čtení a případné modifikaci. Bude znát princip symetrických a asymetrických šifer. Seznámí se s principem elektronického podpisu.
2.2 Historie šifrování První náznaky šifrování či první zmínky o kryptografii můžeme nalézt již před několika tisíci lety. Pokud bychom chtěli být přesnější, je nutno uvést, že první záznamy byli nalezeny v Egyptě přibližně před 4000 lety. Avšak první spolehlivě doložené informace o zašifrování zprávy pochází z roku 480 př. n. l. za období Řecko-perských válek v bitvě u Salamíny. Do historie kryptografie se zapsal i významný římský vojevůdce a politik Julius Caesar, a to vynalezením šifry, která byla pojmenována jako Caesarova šifra. První pokusy se šifrováním však byly značně primitivní. S dnešními šifrovacími metodami neměly nic společného. Členění kryptografie lze znázornit na obrázku 106. KLASICKÁ KRYPTOGRAFIE
MODERNÍ KRYPTOGRAFIE
Do 1. pol. 20. století Obr. 106: Členění kryptografie Zdroj: vlastní
Z obrázku je patrné, že kryptografii lze rozdělit na dva základní druhy, a to kryptografii klasickou a moderní. Klasická kryptografie trvala do přibližně do první poloviny 20. století a vyznačovala se zejména tím, že k šifrování stačilo používat tužky a papír, případně jiné jednoduché pomůcky. S rozvojem přístrojů a počítačové techniky, lze aplikovat složitější postupy při šifrování. Tím se začalo rozvíjet období, které označujeme jako moderní kryptografie. Vývoj kryptografie šel ruku v ruce s vývojem kryptoanalýzy, což je věda, která se naopak zabývá odhalováním šifer.
2.3 Moderní kryptografie Současná doba je charakteristická tím, že rozsáhlé užití výpočetní techniky vede ke zvýšenému objemu zpracovávaných dat. Tato data v sobě nesou ve velké míře důvěrné informace a není proto žádoucí, aby k těmto informacím měly přístup třetí osoby. K ukrytí informací jsou voleny dva druhy utajení, a to technické či programové. Je samozřejmé, že zvolené druhy je možno kombinovat. Jelikož vlastní fyzické zabezpečení (technické) je velmi finančně náročné, stává se 81
softwarové řešení v podstatě levnou záležitostí. Není proto divu, že se uživatelé obrací na kryptografii. Systémy kryptografie používané v současnosti jsou z velké míry založeny na matematických principech. Všechny používané šifry jsou podrobeny důkladné analýze. Známá je také síla šifer a čas, který je potřeba k jejich prolomení. Proces šifrování v současné době je znázorněn na obrázku 1.2. V současnosti se k šifrování velmi často používá klíče. Ten hraje v případě šifer velmi důležitou roli. Jedná se obvykle o posloupnost (obvykle) čísel o délce několika bitů. Běžně se používají 128bitové klíče. Celý proces šifrování je řešen matematickou operací, kde na počátku vstupují data a klíč. Na druhé straně je dešifrování, které je tvořeno opět matematickou operací, která k dešifrování využije opět klíče. Data Klíč
Zašifrovaná data
Otevřená data Klíč
Obr. 107: Proces šifrování za užití klíče Zdroj: vlastní
Používané kryptografické metody se dají rozdělit podle několika hledisek. Mezi první patří rozdělení na jednosměrné a obousměrné šifry. Jednosměrné šifry neumožňují zpětné získání původní informace ze zašifrovaných dat. U obousměrných šifer jsme schopni při znalosti správného klíče ze zašifrovaných dat získat data původní. Nyní si přiblížíme, jak pracují jednosměrné šifry. Jak již bylo řečeno, tyto šifry pracují jedním směrem. Proto zprávu, kterou zašifrujeme, nemůžeme opět rozšifrovat. Přesto se tento systém, i když na první pohled neužitečný, využívá poměrně často. Je užíván zejména k ověření autentičnosti dat či k digitálnímu podpisu. Jako příklad jednosměrných šifer lze uvést tzv. hashovaní funkce.
2.4 Bezpečnostní cíle kryptografie Moderní kryptografie zajišťuje následující bezpečnostní cíle: • Důvěrnost dat – to je utajení informace před neoprávněnými uživateli. •
Integrita dat – tj. zajištění toho, aby data nebyla úmyslně nebo i neúmyslně změněna.
•
Autentizace dat – tj. ověření identity daných entit (uživatele, počítače, zařízení, programu, procesu, apod.).
•
Nepopiratelnost – zajišťuje, aby daný subjekt později nemohl popřít to, co předtím vykonal. Nepopiratelnost může být mnoha typů a rozeznáváme: • nepopiratelnost původu dokazuje, že původce zprávu vytvořil, • nepopiratelnost odeslání dokazuje, že průvodce zprávu odeslal, • nepopiratelnost podání dokazuje, že doručovatel přijal zprávu k přenosu, • nepopiratelnost přenosu dokazuje, že doručovatel doručil zprávu, • nepopiratelnost příjmu dokazuje, že příjemce přijal zprávu, • nepopiratelnost znalosti dokazuje, že příjemce se se zprávou seznámil.
•
Důvěryhodné vyznačení času – garantované připojení času k události.
•
Důvěryhodný monitoring – garantovaný záznam události.
•
Řízení přístupu – tj. zajištění toho, aby pouze oprávněné subjekty měli přístup k definovaným subjektům.
•
Autorizace – zajištění toho, že určitou činnost mohou vykonávat pouze určité oprávněné subjekty.
Bezpečnostním cílem může být například také ochrana doby trvání nějaké operace v informačním systému nebo ochrana toho, že nějaká událost v systému v daném čase nastala (například, že se na komunikačním kanálu odesílá zpráva).
82
2.5 Základní pojmy Pro naši další práci objasněme základní používané pojmy, s nimiž se v oblasti šifrování zpráv můžeme setkat. Mezi jeden ze základních patří pojem kryptografie. Slovo kryptografie pochází z řečtiny – kryptós je skrytý a gráphein znamená psát. Někdy je pojem obecněji používán pro vědu o čemkoli spojeném se šiframi. Kryptografie je nauka o metodách utajování smyslu zpráv. Zabývá se převodem a utajováním obsahu zpráv, k čemuž využívá různých metod a speciálních znalostí. Opakem kryptografie je kryptoanalýza. Ta se zabývá převedením zašifrované informace zpět do čitelné podoby, a to bez znalosti klíče. Cílem je tedy získat zpětně čitelný text pro uživatele. Dále si definujme, co je to vlastně šifrovací algoritmus. Jedná se o proces transformace, která převede otevřený text (plain-text) na šifrovaný text (cipher-text) a naopak. Při procesu zašifrování transformace probíhá pomocí klíče pro zašifrování, při odšifrování se pak postupuje analogicky pomocí klíče pro odšifrování. Předposledním používaným pojmem je steganografie. Jejím úkolem je skrýt samostatnou existenci zprávy. A na závěr posledním pojmem je šifra a šifrování. Šifrování lze chápat jako nahrazení otevřeného textu zdánlivě nesrozumitelným a nesmyslně vypadajícím kódem. Problém je možné řešit dvěma způsoby: Transpozicí – změnou pořadí znaků ve zprávě. Substitucí – náhradou znaků zprávy zcela jinými znaky. Transpoziční šifry bývají velmi účinné. Při krátké třicetiznakové zprávě se dostáváme na 2,65.1032 možností permutací znaků. Toto množství možných řešení nelze efektivně prohledat ani za použití nejmodernější výpočetní techniky. Každý šifrovaný text je navíc zbaven všech možných prvků, které by mohly tvořit nápovědu při dešifrování, například dělení na slova nebo odstranění diakritiky a interpunkčních znamének. Příklad: ukázka transpoziční šifry SCSADFGERXCSWBKLUIOPSCTANCVDFHJKLOUPNNBVXFSDARTFGJKLMER
Bez znalosti permutačního předpisu je zpráva šifrována vcelku bezpečně a prostor možných řešení je velmi velký. Proto prolomení zkoušením všech kombinací není možný. Problémem je, že příjemce zašifrované zprávy, musí znát klíč, který mu musí být nějakým utajeným způsobem dodán. Při běžné komunikaci je to velmi obtížné a vystavujeme se tak prozrazení. Substituční šifrování je založeno na systematické náhradě znaků otevřené zprávy za znaky nebo symboly jiné. Pokud se použije pro záměnu určitého znaků vždy pouze jeden šifrovaný symbol jedná se o monoalfabetickou šifru. Jsou-li šifrové znaky, nahrazující původní znak, střídány, jde o tzv. polyalfabetickou šifru.
2.6 Symetrické a asymetrické šifry Symetrické šifry: Symetrické šifrovací systémy jsou příkladem obousměrných šifer. Tyto obousměrné šifry dovolují zpětně bez znalosti klíče získat data původní. Při symetrickém šifrování se používá ke kódování a dekódování pouze jeden klíč. Mezi základní výhodu tohoto způsobu šifrování patří rychlost. Jako nevýhodu je nutné uvést, že jak odesílatel, tak příjemce musí znát klíč. Klíč, kterého užijeme u šifrování, musí být dostatečně dlouhý, aby odolal útokům „hrubou silou“. Symetrické šifry se dále dělí na šifry proudové a šifry blokové. Asymetrické šifry: Asymetrické šifrování používá ke své činnosti dva klíče. Jeden z klíčů se nazývá soukromý, druhý veřejný. Pokud je zpráva zašifrována jedním klíčem, může být rozšifrována pouze klíčem druhým a naopak. Klíče tvoří dvojice a musí být vytvořeny současně. Další podmínkou je, aby z jednoho klíče nešel odvodit klíč druhý. Asymetrické šifrování má výhodu v tom, že na rozdíl od symetrického šifrování, nemusíme utajovat klíč. Má ale i své nevýhody. Jednou z nich je rychlost, další pak potvrzení pravosti veřejného klíče. 83
2.7 Kontrolní otázky 1) Vysvětlete princip transpoziční šifry. 2) Vysvětlete princip substituční šifry. 3) Charakterizujte pojem monoalfabetická šifra. 4) Charakterizujte pojem polyalfabetická šifra. 5) Jaký je rozdíl mezi symetrickým a asymetrickým šifrováním?
84
3 Elektronický podpis 3.1 Elektronický podpis V současné době se stáváme svědky zajímavého jevu: u nově vznikajících dokumentů začíná nad tradiční formou převažovat forma elektronická. Některé vznikají přímo v elektronické podobě, jiné převodem z formy tradiční. Dokumenty pořízené v tradiční podobě mohou být opatřeny vlastnoručním podpisem. Vyvstává otázka, jak tento podpis nahradit ve světě elektronickém. Převodem z tradiční podoby do elektronické přicházejí dokumenty o vlastnoruční podpis, který byl jejich součástí, nebo se takový podpis stává nedůvěryhodným. To platí například pro zprávy zaslané faxem. Elektronických dokumentů stále přibývá, jejich předávání je snadné a rychlé a uživatelé si výhody, které tento způsob komunikace přináší, uvědomují. Proto je nezbytné najít metodu, která v elektronickém světě umožní provést úkon odpovídající vlastnoručnímu podpisu. Požadavky na elektronický podpis můžeme vyjádřit pojmy neporušenost, identifikace, nepopiratelnost. Podepsaný dokument nesmí být změněn (neporušenost), musí být možné určit osobu, která se podepsala (identifikace), a zajistit, aby tato osoba nemohla svůj podpis popřít (nepopiratelnost). V případě právního sporu musí být navíc zajištěno neodmítnutí elektronického podpisu (právní akceptování). Pokud elektronický podpis všechny tyto požadavky splňuje, nazýváme jej zaručeným elektronickým podpisem. Na elektronický podpis je možné klást i jiné požadavky, např. požadavek na utajení obsahu dokumentu před nepovolanou osobou nebo požadavek na prokázání existence dokumentu v daném čase. Tyto požadavky nepatří mezi vlastnosti podpisu vlastnoručního, a proto se nestaly ani požadavky na definici podpisu elektronického. V případě potřeby je ale možné je splnit pomocí navazujících služeb, například šifrováním nebo použitím časových razítek.
3.2 Elektronický podpis a jeho užití Podle zákona o elektronickém podpisu se takovým podpisem rozumí údaje v elektronické podobě zašifrované privátním klíčem, které jsou připojené k datové zprávě nebo jsou s ní logicky spojené a které umožňují ověření totožnosti podepsané osoby ve vztahu k datové zprávě. Datovou zprávou jsou data, která lze přenášet prostředky pro elektronickou komunikaci a uchovávat na záznamových médiích, používaných při zpracování a přenosu dat. Podpis se vždy vztahuje na data, ke kterým byl připojen. Elektronický podpis je v podstatě číslo, přesně řečeno se ale jedná o posloupnost znaků (bitů), v binárním zápisu se jedná o posloupnost nul a jedniček (bitů). Od „běžných“ čísel se ale elektronický podpis odlišuje tím, že to bývá velmi velké číslo (například 1024, 2048 nebo dokonce až 4096 bitů) a jeho výpočet nebo ověření je dosti složitý úkon, který nelze provádět ručně, ale pouze s pomocí počítače. Elektronický podpis je tedy výsledkem složitých matematických operací. Výsledek je závislý na podepisující osobě a podepisovaném dokumentu. Díky těmto závislostem je právně ověřitelný, což je nesmírně důležité. Pro ověření se užívají dva druhy klíčů – privátní a veřejný. Klíč privátní (tajný) slouží k podepisování dokumentů, musí být uchován v tajnosti a jeho znalost přísluší pouze jeho vlastníkovi. Klíč veřejný slouží ke čtení a ověřování identity autora. Používá se jako párové heslo k privátnímu klíči – tzn. co se zašifruje veřejným klíčem lze dešifrovat pouze odpovídajícím privátním klíčem a naopak. Všichni pak můžou bezpečně komunikovat s vlastníkem privátního klíče a mají jistotu, že jejich data, zašifrovaná veřejným klíčem, budou použitelná jen vlastníkovi privátního klíče. Jakýkoli pokus podepsat dokument nesprávným privátním klíčem nebo pokus o změnu samotného podepsaného dokumentu vyvolá při ověření správnosti podpisu chybové hlášení. 85
Bez znalosti privátního klíče uživatele nelze tedy vytvořit správný soubor čísel, který by mohl nahradit platný podpis. Elektronickým podpisem může být i jméno napsané z klávesnice. Důvěra v takový podpis ale nemůže být příliš vysoká. Takový podpis může sloužit pouze jako informace pro příjemce. V centru zájmu jsou takové formy elektronického podpisu, které z tohoto hlediska poskytují vyšší stupeň důvěry. Jedná se o zaručený elektronický podpis, který podle zákona o elektronickém podpisu musí splňovat následující požadavky: Je jednoznačně spojen s podepisující osobou. Umožňuje identifikaci podepisující osoby ve vztahu k datové zprávě. Byl vytvořen a připojen k datové zprávě pomocí prostředků, které podepisující osoba může udržet pod svou výhradní kontrolou. Je k datové zprávě, ke které se vztahuje, připojen takovým způsobem, že je možno zjistit jakoukoliv následnou změnu dat. Zaručené elektronické podpisy umožňuje vytvářet technologie digitálního podpisu. Ta je založena na matematických a kryptografických metodách (postupech), jejichž znalost není na straně uživatele předpokladem běžného používání této technologie. Předpokládá se, že v budoucnu bude zaručený elektronický podpis založen i na dalších metodách, například biometrických (biometrie1) charakteristikách člověka – otisku prstu, obrazu oční sítnice, zvuku hlasu aj. Možnosti využití elektronického podpisu: Ve státní správě a samosprávě - jakmile občan získá právně platnou možnost podepisovat se elektronickým podpisem a tedy identifikovat se vůči úřadům na dálku, může většina komunikace mezi ním a státní správou či samosprávou probíhat elektronicky: podání nejrůznějších prohlášení a daňových přiznání, přihlášek a odhlášek, žádost o výpis z rejstříku trestů, žádosti o sociální dávky apod. Občané ušetří spoustu času a státní správa může ušetřit vysoké náklady za tisk a distribuci papírových dokumentů. V bankovnictví - klient „elektronické“ či „přímé“ banky má možnost disponovat svým účtem nejčastěji po Internetu. Všechny příkazy odesílané bance přitom podepisuje svým elektronickým podpisem. Výhody jsou zřejmé: klient nemusí stát frontu v bance, může své bankovní příkazy zadávat 24 hodin denně a má neustále z domova či kanceláře přehled o stavu svého účtu. Banka ušetří čas svých úředníků na rutinních operacích a může ho věnovat rozvíjení služeb pro klienty v případech, které na dálku vyšetřit nelze. Banka také výrazně šetří náklady, protože bankovní operace uskutečněná v kamenné pobočce stojí 50 korun českých, kdežto uskuteční-li se přes Internet, náklady činí pouhých 60 haléřů. Pro elektronické obchodování - zákazník může nakupovat v elektronických prodejnách a obchodních domech. Nemusí stát ve frontách, sedí v teple domova a přitom stihne projít mnohem více obchodů, vybrat si z většího množství zboží a najít příznivější cenu. Navíc může navštívit i obchody, které by pro velkou vzdálenost osobně nikdy navštívit nemohl. Výhodu je také to, že elektronické obchody mají otevřeno 24 hodin denně, 7 dní v týdnu. Těchto pozitiv mohou využít i obchodní partneři obchodující, jak je běžným zvykem, na základě smluv, objednávek a faktur. Díky elektronické komunikaci mají možnost obchodovat bez ohledu na vzdálenosti a časová pásma a přitom velice rychle, pohodlně, efektivně. Výsledkem jsou menší skladové zásoby na straně dodavatele i objednatele a rychlejší obrat kapitálu, tedy vyšší efektivita obchodování s menšími náklady. V obou kategoriích elektronického obchodu hraje elektronický podpis nezastupitelnou roli. Zákazník, stejně jako obchodník budou mít záruku, že člověk, se kterým obchodují a kterého třeba nikdy osobně neuvidí, je existujícím partnerem. Stejně tak poskytuje garanci, že zprávy, dokumenty a faktury dopravené po komunikačních sítích nebyly cestou změněny a že jejich autorem je skutečně jejich obchodní partner.
Výhody elektronického podpisu 1
Biometrie je metoda autentizace založená na rozpoznávání fyzických charakteristik subjektu - živé osoby. Metoda vychází z přesvědčení, že některé fyzikální charakteristiky jsou pro každého živého člověka jedinečné a neměnitelné.
86
Elektronický podpis umožňuje ověření identity podepisujícího – příjemce bezpečně ví, kdo je autorem či odesílatelem zprávy. Ověření integrity zprávy (že zpráva nebyla změněna) – příjemce má jistotu, že zpráva nebyla změněna v průběhu transportu, což ruční podpis může zajistit jen stěží. Zaručuje nepopiratelnost zprávy – odesílatel nemůže popřít, že danou zprávu s daným obsahem opravdu odeslal. Nenapodobitelnost podpisu – prostředky k podpisování může mít daná osoba pod svou výhradní kontrolou.
3.3 Certifikační autorita Pro kvalitní a bezpečné vytvoření elektronického podpisu je důležité znát spojení veřejného klíče s jeho majitelem. K tomuto je využíván certifikát – elektronicky podepsaný veřejný klíč, na základě kterého se osvědčuje, že určitý soukromý klíč vlastní konkrétní osoba. Veškerá manipulace a problematika správy, distribuce a uchovávání veřejných klíčů je dána do správy certifikační autority. Tato instituce vystupuje v rámci komunikace dvou stran jako třetí nezávislý subjekt, který pracuje na právním základě. Jeho činností je generování, obnova certifikátů klíčů, kontrola a registrace uživatelů. Mezi akreditované poskytovatele certifikačních služeb v ČR patří: • • •
První certifikační autorita, a.s. PostSignum QCA (Česká pošta) Identity, a.s.
3.4 Zavedení elektronického podpisu Vlastní podepsání elektronického dokumentu je celkem jednoduché a to hlavně z toho důvodu, že za celý průběh zodpovídá specializovaný software, takže uživatel pouze zvolí dokument a vydá potřebný příkaz. Elektronický podpis přitom vzniká následujícím způsobem: vypočte se hash (otisk) dokumentu, tento se zašifruje s použitím privátního klíče. Tím je elektronický podpis vytvořen a následně je přiložen k dokumentu. Příjemci se odešle původní dokument (ten není nijak šifrován ani jinak chráněn před zraky nepovolaných osob), elektronický podpis a certifikát. Příjemce pak postupuje tak, že k dokumentu znovu vypočte hash a pomocí veřejného klíče odšifruje elektronický podpis, čímž získá původní otisk – jejich porovnáním pak zjistí, zda dokument nebyl pozměněn, tj. zda se jedná skutečně o dokument, který odesílatel napsal a podepsal. Proto, aby se stal elektronický podpis důvěryhodný, musí podepisovaná osoba v některých případech používat elektronický podpis založený na certifikátu. Elektronický podpis je v takovém případě pro každou podepsanou zprávu jiný a odvozuje se od této zprávy. Právě takovýto podpis se nazývá zaručeným elektronickým podpisem. Certifikát lze získat od poskytovatele certifikačních služeb. Pro získání certifikátu u některé certifikační autority stačí pouze platná adresa elektronické pošty (jiná ověřuje totožnost pouhým vizuálním srovnáním fyzické podoby žadatele s oficiální fotografií v dokladech v kanceláři certifikační autority). Certifikační autorita plní dvě základní funkce: Certifikační – zaručující, že deklarovaný veřejný klíč přísluší dané osobě. Validační – potvrzující platnost certifikátu. V případě certifikace se jedná o vydávání certifikátů uživatelům, kdy certifikát je dokument, který stvrzuje, že veřejný klíč (uvedený na certifikátu) patří jednoznačně dané osobě. Certifikát zároveň obsahuje další informace týkající se uživatele, doby platnosti klíče, informace o používání klíče a informace o certifikační autoritě. Certifikát je podepsán elektronickým podpisem certifikační autority. V případě komunikace mezi dvěma uživateli si uživatelé nejdříve ověří podpis certifikátu pomocí veřejného klíče certifikační autority. V daném případě se požadavek na důvěryhodnost vztahuje pouze k certifikační autoritě. 87
V případě validace se uživatel dotazuje u certifikační autority na platnost certifikátu svého partnera. Systém dotazů může být řešen on-line nebo využitím seznamu neplatných certifikátů, tj. seznamu certifikátů, jejichž platnost byla ukončena před stanovenou dobou platnosti.
3.5 Zákon o elektronickém podpisu Zákon č. 227/2000 Sb., o elektronickém podpisu a o změně některých dalších zákonů včetně pozdějších novelizací a vyhláškou Úřadu pro ochranu osobních údajů č. 366/2001 Sb., upřesňují podmínky § 6 výše zmíněného zákona specifikující povinnosti poskytovatele certifikačních služeb vydávajícího kvalifikované certifikáty a § 17, který definuje prostředky pro vytváření a ověřování zaručených elektronických podpisů. Certifikační autorita2 zpracovává osobní údaje uvedené uživatelem za účelem poskytování služeb, ochrany zájmu uživatele, předávání osobních údajů třetím stranám, a v případě poskytnutí souhlasu uživatele za marketingovými účely poskytovatele. Osobní data jsou zabezpečována na nejvyšší možné úrovni. Certifikační autorita se při zpracování dat řídí zákonem č. 101/2000 Sb., o ochraně osobních údajů.
2
Certifikační autorita znamená v kryptografii objekt, který vydává digitální certifikáty k použití ostatním zúčastněným. Digitální certifikát je digitálně podepsaný veřejný klíč. CA má v PKI zásadní roli. Existuje mnoho komerčních certifikačních autorit, které za poplatek poskytují své služby. V Česku to je ICA a Česká pošta. Ve světě například Verisign. Poměrně novou záležitostí jsou komunitní CA. Největší a nejznámější je CAcert.org (původem z Austrálie), která má své zástupce i v Česku. Alternativou jsou sítě důvěry, které vznikají vzájemným podepisováním klíčů mezi zúčastněnými uživateli. Na rozdíl od CA nepracují s hiearchickým, nýbrž s distribuovaným modelem vztahů důvěry.
88
Závěr Kolektiv autorů průběžně aplikoval jednotlivé úlohy do výuky posluchačů EPI s.r.o. a pečlivě doplňoval podrobnější popis úloh podle toho, jak posluchači na text reagovali. Závěrem je třeba poděkovat odborné asistentce Ing. I. Matuškové, DiS, BBS za editaci a grafické zpracování textu a za vedení pilotního provozu a panu Bc. F. Koptovi za pomoc při realizaci pilotního provozu na kampusu EPI s.r.o. Hodonín, Kunovice i Kroměříž. Kolektiv autorů přeje všem dalším uživatelům hodně radosti ze studia.
89
Literatura [1]
BERAN, R. Algoritmy [online]. 2012 [cit. 2012-11-23]. Dostupné z WWW: http://www.beranr.webzdarma.cz/algoritmy/algoritmy.html
[2]
VANÍČEK, J. Teoretické ISBN 80-903962-4-1
[3]
Dev-C++ 5.1.1.0. Integrované vývojové prostředí. [software]. 2005 [cit. 1999-12-10]. Dostupné z: http://orwelldevcpp.blogspot.cz/
[4]
SHCILDT, R. Nauč se sám C++. Praha: SoftPress, 2006.
90
základy
informatiky.
Praha:
ALFA,
2007.
s.
431.
Název: Teoretické základy informatiky pro ekonomy II. Autor: Prof. Ing. Oldřich Kratochvíl, Ph.D., CSc., MBA, Dr.h.c. Ing. Jindřich Petrucha, Ph.D. Ing. Robert Jurča, Ph.D.
Vydavatel, nositel autorských práv, vyrobil: Evropský polytechnický institut, s.r.o., Osvobození 699, 686 04 Kunovice Náklad:
100 ks
Počet stran:
90
Rok vydání:
2014
ISBN 978-80-7314-303-9 91
92