Tohle jsou řešené úlohy z učebnice céčka. Určitě je skoro vždycky víc správných řešení, někdy i lepších. Programy používají spíše krkolomné zápisy, abyste si na to zvykali :-) Všechno (skoro) jsem to kompiloval v MSVC++, takže by tam neměly být chyby a mělo by to jít zkompilovat skoro všude. (až na jeden z posledních příkladů na fixed-point, protože LCCčko a myslím ani MinC_Gw neznají typ __int64 to se pak musí použít pomalejší double, nebo něco o stejné délce (obyč long nestačí, přeteče už při 2 na druhou)) Tož do toho : === Kapitola 4 === 1) Napište program, který vytiskne : James Bond "Agent 007" \ # 150 % záruka # / spol. s.r.o. #include <stdio.h> void main() { printf("James Bond \"Agent 007\" \\ # 150 %% záruka # / \nspol. s.r.o. \n"); getchar(); } 2) Napište program, který přečte znak a vytiskne znak s hodnotou o 1 vyšší : vstup : A výstup : B (ASCII 66) #include <stdio.h> void main() { char c; c = getchar(); putchar(c + 1); } nebo #include <stdio.h> void main() { char c; c = getchar(); printf("%c (ASCII %d)\n", c + 1, c + 1); } 3) Napište program, který přečte celé číslo a vytiskne jako hexadecimální : vstup : 127 výstup : 7FH #include <stdio.h> void main() { int i; scanf("%d", &i); printf("%xH \n", i); } 4) Napište program, který připočítává 25% daň : vstup : Zadej cenu bez daně : 100 výstup : Cena s daní : 125 #include <stdio.h> void main() { int i; scanf("%d", &i); printf("%d bez dane, %d s dani \n", i, (i * 125) / 100); } 5) Napište program, který vypočítá obsah obdélníka : vstup : Zadej delku a sirku : 5 4 výstup : Obsah obdelnika o delce 5 a sirce 4 je 20 #include <stdio.h> void main() { int i, j; printf("Zadej delku a sirku : "); scanf("%d %d", &i, &j); printf("Obsah obdelnika o delce %d a sirce %d je %d \n", i, j, i * j); } 6) Napište program, který načte reál. číslo a vypíše jeho celou část : vstup : Zadej reál. číslo : 3.1415928 výstup : Celá část : 3 #include <stdio.h> void main() { float f; scanf("%f", &f); printf("%.0f \n", f); } 7) Napište program, který přečte 3 malá písmena a tiskne je jako 3 velká : vstup : Zadej 3 mala pismena : a b c výstup : ABC #include <stdio.h> void main() { char a, b, c; printf("Zadej 3 mala pismena :"); scanf("%c %c %c", &a, &b, &c); printf("%c %c %c \n", a + 'A' - 'a', b + 'A' - 'a', c + 'A' - 'a'); } 8) Napište program, který přečte 3 velká písmena a tiskne 3 malá obráceně : vstup : Zadej 3 velka pismena : ABC výstup : cba #include <stdio.h> void main() { char a, b, c; printf("Zadej 3 velka pismena :"); scanf("%c %c %c", &a, &b, &c); printf("%c %c %c \n", c - 'A' + 'a', b - 'A' + 'a', a - 'A' + 'a'); } 9) Napište program, který vyzkouší následující výrazy, jsou-li definice int a = 2, b = 2, c = 1, d = 0, e = 4; (vypíše hodnotu) Tím si ozkoušíte jek funguje ++ operátor : výrazy : a) a++ / ++c * --e b) --b * c++ - a c) -b - --c d) ++a - --e e) e / --a * b++ / c++ f) a %= b = d = 1 + e / 2 výstup : Pro výraz XXX a=x b=x c=x d=x e=x, po výrazu a=x b=x c=x d=x e=x #include <stdio.h> void main() { int a = 2, b = 2, c = 1, d = 0, e = 4; int hodn; printf("Testuji vyraz a++ / ++c * --e\n"); printf("a = %d, b = %d, c = %d, d = %d, e = %d\nPo vyrazu :\n", a, b, c, d, e); hodn = a ++ / ++ c * -- e; printf("a = %d, b = %d, c = %d, d = %d, e = %d\nHodnota vyrazu : %d\n", a, b, c, d, e, hodn); } 10) Napište program, který pískne #include <stdio.h> void main() { putchar('\a'); } === Kapitola 5 === 1) - Napište pomocí ternárního operátoru program, který rozhodne které ze tří zadaných čísel je největší. #include <stdio.h> void main() { int a, b, c; int x; printf("Zadej tri cisla : "); scanf("%d%d%d", &a, &b, &c); x = (a > b)? ((a > c)? a : c) : ((b > c)? b : c); // pro prehlednost (jinak to mohlo byt primo v printf // a nemuselo tu byt zadne x) printf("Nejvetsi je %d !\n", x); getchar(); } 2) - Napište program, který seřadí tři zadaná čísla vzestupně. #include <stdio.h> void main() { int a, b, c; // zadane int x, y, z; // serazene printf("Zadej tri cisla : "); scanf("%d%d%d", &a, &b, &c); x = (a > b)? ((a > c)? a : c) : ((b > c)? b : c); z = (a < b)? ((a < c)? a : c) : ((b < c)? b : c); if((b > a && a > c) || (c > a && a > b)) y = a; else if((a > b && b > c) || (c > b && b > a)) y = b; else /*if((b > c && c > a) || (a > c && c > b))*/ y = c; // prostredni je slozitejsi printf("Sestupne : %d, %d, %d !\n", x, y, z); getchar(); } 3) - Napište program, který zjistí zda je zadané číslo liché (použijte modulo %) #include <stdio.h> void main() { int a; printf("Zadej cislo : "); scanf("%d", &a); if(a % 2) // po deleni dvema zustane zbytek printf("Liche !\n"); else printf("Sude !\n"); getchar(); } 4) - Napište program, který vytiskne "+" / "-" pokud je zadané číslo sudé nebo liché. #include <stdio.h> void main() { int a; printf("Zadej cislo : "); scanf("%d", &a); putchar((a % 2)? '-' : '+'); getchar(); } 5) - Napište program, který zjistí zda zadané číslo je 1 nebo 3 nebo 5 a vypíše "A", nebo zda je 2 nebo 4 nebo 6 a vypíše "B" nebo vypíše "nevím" (použijete case) #include <stdio.h> void main() { int a; printf("Zadej cislo : "); scanf("%d", &a); switch(a) { case 1: case 3: case 5: printf("A \n"); break; case 2: case 4: case 6: printf("B \n"); break; default: printf("Nevim \n"); } getchar(); } 6) - Napište program, který se zeptá na počet chyb a vypíše : - pokud počet piv je nula - "Nic si nepil" - větší než nula a menší (rovno) než tři - "Pohodička" - větší než tři a menší (rovno) než pět - "V náladě" - větší než pět a menší nebo deset - "Pod stůl" - větší než deset - "Jako puma !" #include <stdio.h> void main() { int a; printf("Zadej pocet piv : "); scanf("%d", &a); if(a <= 0) printf("Nic si nepil\n"); else if(a <= 3) printf("Pohodicka\n"); else if(a <= 5) printf("V nalade\n"); else if(a <= 10) printf("Pod stul\n"); else /*if(a > 10)*/ printf("Jako puma !\n"); getchar(); } === Kapitola 6 === 1) - Napište program, který vytiskne násobky tří od tří do dvaceti. Nepopužívejte % (dělení modulo) #include <stdio.h> void main() { int i; for(i = 3; i < 20; i += 3) printf("%d \n", i); getchar(); } 2) - Napište program, který vytiskne ascii tabulku (znaky od 32 do 128) #include <stdio.h> void main() { int i; printf("Ascii tabulka \n"); for(i = 32; i <= 128; i ++) { printf("%c ", i); if((i - 32) % 16 == 0) printf("\n"); } getchar(); } 3) - Napište program, který čte čísla, dokud nezadáte 999 a potom vytiskne jejich průměr. #include <stdio.h> void main() { int cislo, pocet, soucet; cislo = 0; pocet = -1; soucet = 0; // dulezite do { pocet ++; soucet += cislo; scanf("%d", &cislo); } while(cislo != 999); // takhle tam ta 999 nebude zapocitana /* pocet = 0; soucet = 0; // dulezite do { scanf("%d", &cislo); pocet ++; soucet += cislo; } while(cislo != 999); // takhle by tam byla zapocitana */ printf("Prumer je %d\n", soucet / pocet); getchar(); } 4) - Napište program, který vytiskne posloupnost čísel 1 5 13 29 od 1 do 500 (vždycky další číslo je (předchozí * 2) + 3) #include <stdio.h> void main() { int i; for(i = 1; i < 500; i = i * 2 + 3) printf("%d \n", i); getchar(); } 5) - Napište program, který vypíše tabulku prvočísel od 1 do 100. Použijte % (dělení modulo) #include <stdio.h> void main() { int i, j; for(i = 1; i < 100; i ++) { for(j = 2; j <= i; j ++) { if((i % j) == 0) break; } // pokud je necim delitelne, vyskoci z cyklu if(j == i) printf("%d, ", i); // husty, co ? pokud je to prvocislo, dojde j az do i !! if(i == 50) putchar('\n'); } getchar(); } 6) - Napište program, vytisknuvší tabulku mocnin zadaného čísla od 0 do 10 #include <stdio.h> void main() { int i, n, m; printf("Zadej cislo : "); scanf("%d", &n); for(i = 0, m = 1; i <= 10; i ++, m *= n) printf("%d ^ %d = %d \n", n, i, m); getchar(); } === Kapitola 4b === 1) Napište program, kopírující obsah souboru a.txt do b.txt #include <stdio.h> void main() { FILE *fr, *fw; int c; fr = fopen("a.txt", "r"); fw = fopen("b.txt", "w"); // otevreme pro zapis if(fr == NULL || fw == NULL) { printf("Soubor nejde otevrit !\n"); if(fr != NULL) fclose(fr); if(fw != NULL) // před koncem programu musíme fclose(fw); // uzavřít všechny soubory getchar(); return; } while((c = fgetc(fr)) != EOF) fputc(c, fw); // kopíruje až do konce fclose(fr); fclose(fw); getchar(); } 2) Zkuste napsat program, který spočítá mezery v souboru Text.txt #include <stdio.h> void main() { int c, n_mez; FILE *fr; fr = fopen("Test.txt", "r"); if(fr == NULL) { printf("Soubor Test.txt nejde otevrit !\n"); getchar(); return; } n_mez = 0; // důležité ! while((c = fgetc(fr)) != EOF) { if(c == ' ') n_mez ++; } // počítá mezery fclose(fr); printf("V souboru Test.txt je %d mezer\n", n_mez); getchar(); } 3) Napište program, který spočítá slova v souboru Text.txt #include <stdio.h> void main() { int c, c_predch, n_slov; FILE *fr; fr = fopen("Test.txt", "r"); if(fr == NULL) { printf("Soubor Test.txt nejde otevrit !\n"); getchar(); return; } c_predch = ' '; n_slov = 0; // důležité ! while((c = fgetc(fr)) != EOF) { if((c == ' ' || c == '\n') && (c_predch != ' ' && c_predch != '\n')) n_slov ++; c_predch = c; } // počítá slova if(c_predch != ' ' && c_predch != '\n') n_slov ++; // spocita posledni slovo za kterym je EOF a ne mezera fclose(fr); printf("V souboru Test.txt je %d slov\n", n_slov); getchar(); } 4) Pokuste se o program, který spočítá samohlásky v souboru Text.txt #include <stdio.h> void main() { int c, n_sam; FILE *fr; fr = fopen("Test.txt", "r"); if(fr == NULL) { printf("Soubor Test.txt nejde otevrit !\n"); getchar(); return; } n_sam = 0; // důležité ! while((c = fgetc(fr)) != EOF) { if(c >= 'A' && c <= 'Z') c += 'a' - 'A'; // převede píseny na maly switch(c) { case 'a': case 'e': case 'i': case 'o': case 'u': case 'y': n_sam ++; } } // počítá samohlásky fclose(fr); printf("V souboru Test.txt je %d samohlasek\n", n_sam); getchar(); } === Kapitola 7 === 1) - Napište program, který pomocí makra zjistí pokud je zadané číslo liché. #include <stdio.h> #define Liche(num) ((num) % 2) void main() { int n; printf("Zadej cislo : "); scanf("%d", &n); if(Liche(n)) printf("Liche \n"); else printf("Sude \n"); getchar(); } 2) - Napište makro, které vybere prostřední ze tří zadaných čísel (velikostně) #include <stdio.h> #define Mid(a,b,c) ((((b) > (a) && (a) > (c)) || ((c) > (a) && (a) > (b)))? (a) \ : ((((a) > (b) && (b) > (c)) || ((c) > (b) && (b) > (a)))? (b) : (c))) // at zije zmatek v zavorkach !!! void main() { int a, b, c; printf("Zadej tri cisla : "); scanf("%d%d%d", &a, &b, &c); printf("Prostredni : %d!\n", Mid(a, b, c)); getchar(); } 3) - Napište které zjistí zda znak je malé písmeno. (hodnota bude větší nebo rovno 'a' a menší nebo 'z') #include <stdio.h> #define SmallChar(chr) ((chr) >= 'a' && (chr) <= 'z') void main() { char c; scanf("%c", &c); if(SmallChar(c)) printf("Male\n"); else printf("Inaci (velke nebo cislo nebo cokoli)\n"); getchar(); } 4) - Napište makro pro třetí mocninu (x * x * x). Vyzkoušejte na : - na_treti(10); - na_treti(i + 10); - na_treti(i * 10); - na_treti(i * j - 3); (i a j jsou zadaná čísla) #include <stdio.h> #define NaTreti(x) ((x) * (x) * (x)) void main() { int n; scanf("%d", &n); printf("%d ^ 3 = %d\n", n, NaTreti(n)); // nekce se mi to vsecko psat :-) getchar(); } 5) - Napište makro pro výpis chybové hlášky a čekání na stisk klávesy. #include <stdio.h> #define Chyba { printf("Nekde nastala chyba, sefe ! \n"); getchar(); } void main() { printf("neco dela ...\n"); Chyba; printf("... neco dela\n"); getchar(); } === Kapitola 8 === Tady mě nic na cvičení nenapadá. Zkuste napsat makra, zaokrouhlující dolů, nahoru a zaokrouhlující (větší než 0.5 nahoru, jinak dolů) #include <stdio.h> #define Okolo(x) ((int)((x) + 0.5)) #define Dolu(x) ((int)(x)) #define Nahoru(x) (((int)(x) - (x) == 0)? (int)(x) : (int)(x) + 1) void main() { double f; for(f = 0; f <= 2; f += 0.1) printf("%f, %d, %d, %d\n", f, Dolu(f), Okolo(f), Nahoru(f)); getchar(); } === Kapitola 9 === 1) - Napište funkci, která rekurzivně spočítá mocninu reálného čísla double Mocnina(double cislo, int kolik) { if(!kolik) return 1; return (cislo * Mocnina(cislo, kolik - 1)); } // jednoduche, ze ? 2) - Napište funkci Max_Tri, která vrátí největší ze tří čísel int Max_Tri(int a, int b, int c) { if(a > b) { if(a > c) return a; else return c; } else { if(c > b) return c; else return b; } return a; // nektere kompilatory muzou rvat, ze // ne vsechny moznosti maji navratovou hodnotu // (tak blbej je myslim jen borland) } 3) - Napište funkci, zjišťující zda je parametr prvočíslo a podle toho vrátí 1 nebo 0 int Prvocislo(int n_cislo) { int i; for(i = 2; i < n_cislo; i ++) if((n_cislo % i) == 0) return 0; // pokud je necim delitelne, vraci 0 return 1; } 4) - Napište funkci pro převod malých znaků na velké a naopak (v jednom) char Zmrv_Ho(char c) { if(c >= 'a' && c <= 'z') return (c + 'A' - 'a'); if(c >= 'A' && c <= 'Z') return (c - 'A' + 'a'); return c; } 5) - Napište funkci, která vypočítá rovnici : x = 7a + 41b - 56c + 14 (a, b, c jsou parametry a x je výsledek) float Divna_Rov(float a, float b, float c) { return 7 * a + 41 * b - 56 * c + 14; // zavorky tam byt nemusi (nemusely byt snad ani v tech predchozich) } 6) - Napište modul pro výpočet obsahu a obvodu kružnice (v .h použijte guarda) /* Kruh.h */ #ifndef KRUH_INCLUDED #define KRUH_INCLUDED #define PI (3.141592653579893238462643383279502884) float Obsah(float f_radius); #endif //KRUH_INCLUDED /* Kruh.c */ #include "Kruh.h" float Obsah(float f_radius) { return f_radius * f_radius * PI; } /* Main.c */ #include <stdio.h> #include "Kruh.h" void main() { printf("Kruh o polomeru %f ma obsah %f.2\n", 5.71, Obsah(5.71)); // lehke, co ? getchar(); // ceka na klavesu } === Kapitola 10 === 1) - Napište program, který čte čísla a postupně je ukládá do pole. (musí se postupně realokovat) Potom když uživatel zadá 999 (to už v poli nebude) program potom prohodí pořadí čísel a pole vytiskne. #include <stdlib.h> #include <stdio.h> void main() { int pocet, cislo; int *pole; int i, z; pocet = 0; // dulezite while(1) { scanf("%d", &cislo); // nacte cislo if(cislo == 999) break; // u 999 skonci if(pocet ++) pole = (int*)realloc(pole, pocet * sizeof(int)); else pole = (int*)malloc(sizeof(int)); if(pole == NULL) { printf("Nedostatek pameti !\n"); getchar(); // pokud je tady takova hlaska po ktere program // hned spadne, je docela slusnost pockat az si // to uzivatel precte aby potom nemusel zkoumat // proc to vlastne spadlo (jako m$ windows :-)) return; } // zvetsi pole pole[pocet - 1] = cislo; // zapise cislo } for(i = 0; i < pocet; i ++) printf("%d ", pole[i]); printf("\n"); // vytiskne pole for(i = 0; i < pocet / 2; i ++) { z = pole[i]; pole[i] = pole[pocet - 1 - i]; pole[pocet - 1 - i] = z; } // prohodi poradi for(i = 0; i < pocet; i ++) printf("%d ", pole[i]); printf("\n"); // vytiskne pole free((void*)pole); // uvolni pamet getchar(); } 2) - Napište program, který v poli seřadí čísla v poli (zadává se jako minule) vzestupně. Na to jsou metody : Bublinková - pole se prochází od začátku až do konce a pokud se najde číslo které je větší než následující, prohodí se s ním. Tohle se opakuje dokud není pole seřazené (takhle se seřadí vzestupně) Shake sort - jako bublinková, jenže pole se prochází tam a zpátky Sentinell - zarážka. to je proměnná, nastavená na velikost pole. Pole se pokaždé projde od začátku k zarážce a najde se největší číslo. To se potom prohodí s posledním. Potom se zarážka sníží a celý proces se opakuje dokud není zarážka nula Quick Sort - Jedna z nejrychlejších metod. Vezmou se dvě proměnné a jedna se nastaví na začátek a druhá na konec. Potom se určí tzv. pivot. To je střední hodnota pole. Normálně se to dělá tak že se vybere hodnota prostředního čísloa mezi proměnnými. Potom se jedna zvyšuje a druhá snižuje a hledají se hodnoty, které jsou na špatné straně (menší než pivot napravo a větší nalevo) ty se pak vzájemně prohodí. Takhle se postupuje dokud se ukazatele nesetkají. Potom se to samé zavolá pro obě půlky pole - je to rekurzivní metoda a z tohohle jste ji asi nepochopili :-) bude v řešení #include <stdlib.h> #include <stdio.h> void Bubble(int *p_pole, int n_pocet) { int i, z, b_change; do { b_change = 0; // zmena = 0 for(i = 1; i < n_pocet; i ++) { if(p_pole[i - 1] > p_pole[i]) { b_change ++; // zmena ! z = p_pole[i - 1]; p_pole[i - 1] = p_pole[i]; p_pole[i] = z; } } // zkusi zda je pole setridene / probublava ... } while(b_change); } void Shake(int *p_pole, int n_pocet) { int i, z, b_change; do { b_change = 0; // zmena = 0 for(i = 1; i < n_pocet; i ++) { if(p_pole[i - 1] > p_pole[i]) { b_change ++; // zmena ! z = p_pole[i - 1]; p_pole[i - 1] = p_pole[i]; p_pole[i] = z; } } // zkusi zda je pole setridene / probublava tam ... if(!b_change) break; // testuje zmeny (pokud nejsou, pole je serazene !) for(i = n_pocet - 1; i > 0; i --) { if(p_pole[i - 1] > p_pole[i]) { b_change ++; // zmena ! z = p_pole[i - 1]; p_pole[i - 1] = p_pole[i]; p_pole[i] = z; } } // zkusi zda je pole setridene / probublava zpatky ... } while(b_change); } void Sentinell(int *p_pole, int n_pocet) { int i, z, max, sentinell; sentinell = n_pocet; // zarazka ukazuje na posledni prvek pole do { max = 0; for(i = 1; i < sentinell; i ++) { if(p_pole[i] > p_pole[max]) max = i; } // najde maximum z = p_pole[max]; p_pole[max] = p_pole[sentinell - 1]; p_pole[sentinell - 1] = z; // prohodi prvky } while(-- sentinell); // nez zarazka dojde na zacatek... } void QSort_Rec(int bottom, int top, int *p_pole) { int i, j, pivot, z; i = bottom; j = top; pivot = p_pole[(bottom + top) / 2]; // urci pivot (jsou i lepsi algorytmy) do { while(p_pole[i] < pivot) i ++; while(p_pole[j] > pivot) j --; if(i <= j) { z = p_pole[i]; p_pole[i] = p_pole[j]; p_pole[j] = z; // prohodi prvky i ++; j --; } } while(i <= j); // qsortink ! if(bottom < j) QSort_Rec(bottom, j, p_pole); if(i < top) QSort_Rec(i, top, p_pole); // rekurzuje useky pole } void QuickSort(int *p_pole, int n_pocet) { QSort_Rec(0, n_pocet - 1, p_pole); // vola se trochu jinak } void main() { int pocet, cislo; int *pole; int i; pocet = 0; // dulezite while(1) { scanf("%d", &cislo); // nacte cislo if(cislo == 999) break; // u 999 skonci if(pocet ++) pole = (int*)realloc(pole, pocet * sizeof(int)); else pole = (int*)malloc(sizeof(int)); if(pole == NULL) { printf("Nedostatek pameti !\n"); getchar(); // pokud je tady takova hlaska po ktere program // hned spadne, je docela slusnost pockat az si // to uzivatel precte aby potom nemusel zkoumat // proc to vlastne spadlo (jako m$ windows :-)) return; } // zvetsi pole pole[pocet - 1] = cislo; // zapise cislo } for(i = 0; i < pocet; i ++) printf("%d ", pole[i]); printf("\n"); // vytiskne pole //Bubble(pole, pocet); //Shake(pole, pocet); //Sentinell(pole, pocet); QuickSort(pole, pocet); // seradi pole for(i = 0; i < pocet; i ++) printf("%d ", pole[i]); printf("\n"); // vytiskne pole free((void*)pole); // uvolni pamet getchar(); } 3) - Napište program, který vytiskne počet a hodnotu parametrů se kterými je volán. Zkuste různé kombinace... (z příkazové řádky) #include <stdio.h> void main(int argc, char **argv) { int i; printf("%d parametru !\n", argc); for(i = 0; i < argc; i ++) printf("%s \n", argv[i]); getchar(); } 4) - Napište funkci Swap(int *a, int *b), která prohodí hodnoty integerů a a b. (Volat se bude Swap(&a, &b);) void Swap(int *a, int *b) { int z; z = *a; *a = *b; *b = z; } pomocí odkazů by to vypadalo takhle : void Swap(int &a, int &b) { int z; z = a; a = b; b = z; } A volá se Swap(a, b); === Kapitola 11 === 1) - Napište program, který bude mít strukturu Kocka s věkem a cenou. Uživatel zadá počet koček a ceny a stáří koček. Program je potom seřadí podle ceny a podle věku a vytiskne (napřed podle ceny a potom podle věku) #include <stdlib.h> #include <stdio.h> struct Cat { char s_name[256]; // jméno int n_age; // věk int n_price; // cena }; /* typedef struct { char s_name[256]; int n_age; int n_price; } Cat; // Non - C++ struktura (MincGW, LCC) */ #define CAT_SORT_BYAGE 0 #define CAT_SORT_BYPRICE 1 void Tisk(Cat *p_cat, int cat_num) { int i; for(i = 0; i < cat_num; i ++) { printf("%3d - %8s, %5d let, %5d $\n", i + 1, p_cat[i].s_name, p_cat[i].n_age, p_cat[i].n_price); } } // tiskne kocky void Sentinell(Cat *p_cat, int n_pocet, int sort_by) { int i, max, sentinell; Cat z; sentinell = n_pocet; // zarazka ukazuje na posledni prvek pole do { max = 0; if(sort_by == CAT_SORT_BYAGE) { for(i = 1; i < sentinell; i ++) { if(p_cat[i].n_age > p_cat[max].n_age) max = i; } } else { for(i = 1; i < sentinell; i ++) { if(p_cat[i].n_price > p_cat[max].n_price) max = i; } } // najde maximum z = p_cat[max]; p_cat[max] = p_cat[sentinell - 1]; p_cat[sentinell - 1] = z; // prohodi prvky } while(-- sentinell); // nez zarazka dojde na zacatek... } // seradi kocky void main(int argc, char **argv) { int cat_num; Cat *p_cat; int i; printf("Zadej pocet kocek, bastarde : "); scanf("%d", &cat_num); // přečte počet koček if((p_cat = (Cat*)malloc(cat_num * sizeof(Cat))) == NULL) { printf("Nedostatek pameti RAM !\n"); getchar(); return; } // naalokuje paměť pro kočky for(i = 0; i < cat_num; i ++) { printf("%d. kocka - zadej jmeno, cenu a stari. \n", i + 1); scanf("%s%d%d", p_cat[i].s_name, &p_cat[i].n_price, &p_cat[i].n_age); } // precte kocky printf("\nKocky :\n"); Tisk(p_cat, cat_num); // vytiskne kocky getchar(); Sentinell(p_cat, cat_num, CAT_SORT_BYAGE); // seradi kocky dle veku printf("\nKocky podle stari :\n"); Tisk(p_cat, cat_num); // vytiskne kocky getchar(); Sentinell(p_cat, cat_num, CAT_SORT_BYPRICE); // seradi kocky dle ceny printf("\nKocky podle ceny :\n"); Tisk(p_cat, cat_num); // vytiskne kocky free((void*)p_cat); // uvolni pamet getchar(); } 2) - Napište program pro evidenci pokojů v hotelu. Bude struktura pokoj, která má číslo pokoje (0 - 50) a je obsazená nebo volná. To bude výčtový typ. Hotel bude mít 5 pokojů a program bude umět zobrazit zabrané a volné pokoje a zadat / uvolnit pokoj. #include <stdio.h> enum Room_Status { Free, // volno Busy // obsazeno }; struct Room { int n_id; // číslo Room_Status r_status; // stav }; /* typedef enum { Free, // volno Busy // obsazeno } Room_Status; typedef struct { int n_id; // číslo Room_Status r_status; // stav } Room; // Non - C++ struktury (MincGW, LCC) */ void Tisk(Room *p_room, int room_num) { int i; for(i = 0; i < room_num; i ++) { printf("Pokoj cislo %2d - %s\n", p_room[i].n_id, (p_room[i].r_status == Free)? "volno" : "obsazeno"); } } // tiskne pokoje void Init(Room *p_room, int room_num) { int i; for(i = 0; i < room_num; i ++) { p_room[i].n_id = i + 1; p_room[i].r_status = Free; } } // pripravi pokoje int Set_Stat(Room *p_room, int room_num, int n_room_id, Room_Status r_stat) { int i; for(i = 0; i < room_num; i ++) { if(p_room[i].n_id == n_room_id) { p_room[i].r_status = r_stat; return 1; } } printf("Toz, tendle pokoj tam nejni !\n"); return 0; } // nastavi status pokoje void main(int argc, char **argv) { Room room[5]; int n_choice; int b_done; Init(room, 5); // připraví pokoje Tisk(room, 5); // tiskne hotel b_done = 1; while(b_done) { do { printf("Rekni co kces ! \n[1 = tiskni pokoje," " 2 = zadej pokoj, 3 = uvolni pokoj, 4 = exit] : "); scanf("%d", &n_choice); } while(n_choice < 1 || n_choice > 4); // přečte co uživatel chce switch(n_choice) { case 1: Tisk(room, 5); break; case 2: printf("Rekni, kterej pokoj chces zadat : "); do { scanf("%d", &n_choice); } while(!Set_Stat(room, 5, n_choice, Busy)); break; case 3: printf("Rekni, kterej pokoj chces uvolnit : "); do { scanf("%d", &n_choice); } while(!Set_Stat(room, 5, n_choice, Free)); break; case 4: b_done = 0; break; } } getchar(); } 3) - Napište program, který bude mít výčtový typ eLumps (na začátku) a vytiskne jména a názvy položek typu. Zkuste použít pole pro názvy. #include <stdio.h> enum eLumps { kEntities = 0, kTextures, kPlanes, kNodes, kLeafs, kLeafFaces, kLeafBrushes, kModels, kBrushes, kBrushSides, kVertices, kMeshVerts, kShaders, kFaces, kLightmaps, kLightVolumes, kVisData, kMaxLumps }; struct { char name[32]; eLumps lump_value; } lumpname[] = { {"kEntities", kEntities }, {"kTextures", kTextures }, {"kPlanes", kPlanes }, {"kNodes", kNodes }, {"kLeafs", kLeafs }, {"kLeafFaces", kLeafFaces }, {"kLeafBrushes", kLeafBrushes }, {"kModels", kModels }, {"kBrushes", kBrushes }, {"kBrushSides", kBrushSides }, {"kVertices", kVertices }, {"kMeshVerts", kMeshVerts }, {"kShaders", kShaders }, {"kFaces", kFaces }, {"kLightmaps", kLightmaps }, {"kLightVolumes", kLightVolumes }, {"kVisData", kVisData }, {"kMaxLumps", kMaxLumps} }; // tabulka jmen a souvisejících hodnot void main(int argc, char **argv) { int i; for(i = 0; i <= kMaxLumps; i ++) printf("%s = %d\n", lumpname[i].name, lumpname[i].lump_value); // takhle to bude fungovat i když budete měnit hodnoty / pořadí enumů getchar(); } 4) - Napište program, který bude mít spojový seznam, kde půjde přidávat prvky, ubírat prvky (obojí na určitou pozici) Po každé operaci se obsah seznamu znovu zobrazí (na jednu řádku) #include <stdlib.h> #include <stdio.h> struct Seznam { struct Seznam *prev, *next; int id; }; /* typedef struct Seznam { struct Seznam *prev, *next; int id; } _Seznam; #define _Seznam Seznam // Non C++ deklarace (je to trochu složitější) */ void Tisk(Seznam *seznam) { if(seznam == NULL) { printf("Seznam = [<prazdny>]\n"); return; } while(seznam->prev != NULL) seznam = seznam->prev; // najde první prvek printf("Seznam = ["); while(seznam != NULL) { printf("%d%s", seznam->id, (seznam->next == NULL)? "]\n" : ", "); seznam = seznam->next; } // tiskne } // velice rafinovaně tiskne seznam Seznam *Add(Seznam *seznam, int n_index, int b_pred, int n_new_id) { Seznam *_sez; Seznam *novy; int i; if(seznam == NULL) { if((seznam = (Seznam*)malloc(sizeof(Seznam))) == NULL) return NULL; // naalokuje novy prvek seznam->id = n_new_id; seznam->prev = NULL; seznam->next = NULL; return seznam; } // pro pripad prazdneho seznamu if(n_index < 0) return seznam; while(seznam->prev != NULL) seznam = seznam->prev; // najde první prvek _sez = seznam; for(i = 0; i < n_index; i ++) { if((seznam = seznam->next) == NULL) return _sez; } // posune se na prvek kam se ma clanek pridat if((novy = (Seznam*)malloc(sizeof(Seznam))) == NULL) return seznam; // naalokuje novy prvek novy->id = n_new_id; // prideli novou hodnotu if(b_pred) { // prida clanek pred novy->prev = seznam->prev; if(seznam->prev != NULL) seznam->prev->next = novy; seznam->prev = novy; novy->next = seznam; // upravi pointery ... } else { // prida clanek za novy->next = seznam->next; if(seznam->next != NULL) seznam->next->prev = novy; seznam->next = novy; novy->prev = seznam; // upravi pointery ... } return seznam; } Seznam *Delete(Seznam *seznam, int n_index) { Seznam *z; int i; if(seznam == NULL) return NULL; if(n_index < 0) return seznam; while(seznam->prev != NULL) seznam = seznam->prev; // najde první prvek for(i = 0; i < n_index; i ++) { if((seznam = seznam->next) == NULL) return 0; } // posune se na prvek kam se ma clanek pridat z = NULL; if(seznam->prev != NULL) { seznam->prev->next = seznam->next; z = seznam->prev; } if(seznam->next != NULL) { seznam->next->prev = seznam->prev; z = seznam->next; } // obnovi spojeni free((void*)seznam); // uvolni pamet return z; } void main(int argc, char **argv) { Seznam *seznam; int n_choice; int n_place; int n_index; int b_exit; seznam = NULL; // připraví strukturu pro použití seznam = Add(seznam, 0, 0, 1); seznam = Add(seznam, 0, 1, 0); seznam = Add(seznam, 1, 0, 2); // cvicne prida par hodnot b_exit = 0; while(!b_exit) { Tisk(seznam); // tiskne seznam do { printf("\nCo po mne vlastne chcete ? \n[1 - pridej, 2 - uber, 3 - exit] :"); scanf("%d", &n_choice); } while(n_choice < 1 || n_choice > 3); // zepta se co uzivatel chce switch(n_choice) { case 1: printf("Zadej novou hodnotu, poradi a 1 = pred / 0 = za :\n"); scanf("%d%d%d", &n_choice, &n_index, &n_place); seznam = Add(seznam, n_index, n_place, n_choice); // 1. prvek ma index 0 ! // prida novy prvek break; case 2: printf("Zadej poradi prvku k smazani : "); scanf("%d", &n_index); seznam = Delete(seznam, n_index); break; case 3: b_exit = 1; break; } // udela co se po nem chce } while((seznam = Delete(seznam, 0)) != NULL) ; // uvolni pamet ;-) getchar(); } === Kapitola 12 === 1) - Dopsat cheater 2) - Napište funkci, která "odřízne" z adresy poslední zpětné lomítko (pokud tam je) char *Lomcovak(char *str) { if(str[strlen(str) - 1] == '\n') str[strlen(str) - 1] = 0; // pokud tam je, tak ho odstrani :-) jednoduche ! return str; } 3) - Napište program, kterému zadáte jména všech svých přítelkyň, ten je uloží do spojového seznamu a seřadí podle jména. Použijte strcmp() #include <stdlib.h> #include <string.h> #include <stdio.h> struct Seznam { struct Seznam *prev, *next; char pritelkyne[16]; }; /* typedef struct Seznam { struct Seznam *prev, *next; char pritelkyne[16]; } _Seznam; #define _Seznam Seznam // Non C++ deklarace (je to trochu složitější) */ void Tisk(Seznam *seznam) { if(seznam == NULL) { printf("Seznam = [<prazdny>]\n"); return; } while(seznam->prev != NULL) seznam = seznam->prev; // najde první prvek printf("Seznam = ["); while(seznam != NULL) { printf("%s%s", seznam->pritelkyne, (seznam->next == NULL)? "]\n" : ", "); seznam = seznam->next; } // tiskne } // velice rafinovaně tiskne seznam Seznam *Add(Seznam *seznam, int n_index, int b_pred, char *n_new_id) { Seznam *_sez; Seznam *novy; int i; if(seznam == NULL) { if((seznam = (Seznam*)malloc(sizeof(Seznam))) == NULL) return NULL; // naalokuje novy prvek strcpy(seznam->pritelkyne, n_new_id); seznam->prev = NULL; seznam->next = NULL; return seznam; } // pro pripad prazdneho seznamu if(n_index < 0) return seznam; while(seznam->prev != NULL) seznam = seznam->prev; // najde první prvek _sez = seznam; for(i = 0; i < n_index; i ++) { if((seznam = seznam->next) == NULL) return _sez; } // posune se na prvek kam se ma clanek pridat if((novy = (Seznam*)malloc(sizeof(Seznam))) == NULL) return seznam; // naalokuje novy prvek strcpy(novy->pritelkyne, n_new_id); // prideli novou hodnotu if(b_pred) { // prida clanek pred novy->prev = seznam->prev; if(seznam->prev != NULL) seznam->prev->next = novy; seznam->prev = novy; novy->next = seznam; // upravi pointery ... } else { // prida clanek za novy->next = seznam->next; if(seznam->next != NULL) seznam->next->prev = novy; seznam->next = novy; novy->prev = seznam; // upravi pointery ... } return seznam; } Seznam *Delete(Seznam *seznam, int n_index) { Seznam *z; int i; if(seznam == NULL) return NULL; if(n_index < 0) return seznam; while(seznam->prev != NULL) seznam = seznam->prev; // najde první prvek for(i = 0; i < n_index; i ++) { if((seznam = seznam->next) == NULL) return 0; } // posune se na prvek kam se ma clanek pridat z = NULL; if(seznam->prev != NULL) { seznam->prev->next = seznam->next; z = seznam->prev; } if(seznam->next != NULL) { seznam->next->prev = seznam->prev; z = seznam->next; } // obnovi spojeni free((void*)seznam); // uvolni pamet return z; } Seznam *Swap(Seznam *a, Seznam *b) { a->next = b->next; b->next = a; b->prev = a->prev; a->prev = b; if(b->prev != NULL) b->prev->next = b; if(a->next != NULL) a->next->prev = a; return b; /* char c[256]; strcpy(c, b->pritelkyne); strcpy(b->pritelkyne, a->pritelkyne); strcpy(a->pritelkyne, c); // neprilis dokonale, kdyz uz mame spojovy seznam return a; */ } // prohodi dva prvky (predpoklada ze jsou vedle sebe, a je pred b) Seznam *Sort(Seznam *seznam) { Seznam *prvni; int b_modify; if(seznam == NULL) return NULL; do { b_modify = 0; // modify na nulu prvni = seznam; while(prvni->prev != NULL) prvni = prvni->prev; // najde první potvoru (pri prohazovani se muze zmeni poradi seznamu) while(prvni->next != NULL) { if(strcmp(prvni->pritelkyne, prvni->next->pritelkyne) > 0) { b_modify = 1; prvni = Swap(prvni, prvni->next); } prvni = prvni->next; } // bublinkuje } while(b_modify); // řádí s přítelkyněmi return seznam; } // pouziva bubble sort ... void main(int argc, char **argv) { char nova_pritelkyne[16]; // pozor na dlouha jmena ! Seznam *pritelkyne; pritelkyne = NULL; // připraví strukturu pro použití printf("Zadavej jmena svych pritelkyn, seznam se ukonci jmenem \"-\" \n"); while(1) { scanf("%s", nova_pritelkyne); if(strcmp(nova_pritelkyne, "-")) pritelkyne = Add(pritelkyne, 0, 0, nova_pritelkyne); else break; } // zadavani Tisk(pritelkyne); // tiskne seznam printf("\nSerazene podle abecedy :\n"); pritelkyne = Sort(pritelkyne); // seradi pritelkyne Tisk(pritelkyne); // tiskne seznam while((pritelkyne = Delete(pritelkyne, 0)) != NULL) ; // uvolni pamet ;-) getchar(); } 4) - Napište funkci, která z textu "bla x:10 bla y: 15 bla z:-3 bla .." vytáhne hodnoty x, y a z. (výraz se bude číst z klávesnice, takže je potřeba ošetřit chyby) // !!! musíte mít na paměti, že pokud napíšete do stringu mezeru, // scanf použije jen část před mezerou (muselo by se použít while(getchar() != '\n')) #include <string.h> #include <stdio.h> #include <math.h> // funkce atof() void Parse_It(char *str) { float x, y, z; char *p_chr; int n_err; p_chr = str; while(*p_chr) { if(*p_chr >= 'a' && *p_chr <= 'z') *p_chr += 'A' - 'a'; p_chr ++; } // jen velká písmena printf(str); n_err = 0; // bez chyb if((p_chr = strstr(str, "X:")) == NULL) { n_err ++; x = 0; } else x = (float)atof(&p_chr[2]); // X - zkusí najít "X:" a za ním bude číslo if((p_chr = strstr(str, "Y:")) == NULL) { n_err ++; y = 0; } else y = (float)atof(&p_chr[2]); // Y if((p_chr = strstr(str, "Z:")) == NULL) { n_err ++; z = 0; } else z = (float)atof(&p_chr[2]); // Z printf("X = %.2f\nY = %.2f\nZ = %.2f\nZaznamenano %d chyb.\n", x, y, z, n_err); // vytiskne výsledek } void main(int argc, char **argv) { char str[256]; scanf("%s", str); Parse_It(str); getchar(); } 5) - Napište funkci, která najde v zadaném stringu znak "x" a až do konce text vyplní tečkami. (x tam zůstane) #include <string.h> #include <stdio.h> void Do_X(char *str) { int trigger; trigger = 0; // triger = angl. spouštěč while(*str) { // to samý jako str[0] != 0 if(trigger) *str = '.'; if(*str == 'x' || *str == 'X') trigger = 1; str ++; } } void main(int argc, char **argv) { char str[256]; scanf("%s", str); Do_X(str); printf("%s\n", str); getchar(); } === Kapitola 13 === 1) - Napište program pro rotaci bitů (ne posun !) a vytiskněte výsledky. #include <stdio.h> // char má 8 bitů - nebude fungovat pro int (muselo by se změnit číslo 0x80) unsigned char Rotate_Byte_Left(unsigned char c) { if(c & 0x80) { // 80Hex = 10000000Bin return (c << 1) | 1; } else return (c << 1); } unsigned char Rotate_Byte_Right(unsigned char c) { if(c & 1) { // 1Dec = 00000001Bin return (c >> 1) | 0x80; // 80Hex = 10000000Bin } else return (c >> 1); } void main(int argc, char **argv) { int i; printf("Zadej číslo 0-255 : "); scanf("%d", &i); printf("%d - vpravo = %d, vevo = %d\n", i, (int)Rotate_Byte_Right((unsigned char)i), (int)Rotate_Byte_Left((unsigned char)i)); // počítá a tiskne výsledky getchar(); } 2) - Napište program pro převod čísel mezi soustavama. Bude se vám hodit (i když kalkulačka pod win i ta na stole to umí taky :-)) // pro zjednodušení zadáváte jen číslo a program ho prožene // všema konverzema tam a zase zpátky (nechtělo se mi psát kontroly chyb) // taky sem to napsal tak, aby převod byl víceméně intuitivní // a (snad snadno :-) ) pochopitelný #include <string.h> #include <stdlib.h> #include <stdio.h> char *Dec_to_Bin(int num) { char *tmp; int i; tmp = (char*)malloc(17); tmp[16] = 0; for(i = 0; i < 16; i ++) tmp[i] = ((num >> (15 - i)) & 1)? '1' : '0'; // postupně čte jednotlivé bity čísla (16 bitů) return tmp; } char *Dec_to_Hex(int num) { char *tmp; int i, n; tmp = (char*)malloc(5); tmp[4] = 0; for(i = 0; i < 4; i ++) { n = (num >> (12 - 4 * i)) & 0xf; // odizoluje čtveřici čísel if(n < 10) tmp[i] = '0' + n; else tmp[i] = 'A' + n - 10; // převede do hexa } return tmp; } char *Hex_to_Bin(char *num) { char *tmp, c; int i, l; tmp = (char*)malloc(17); l = (signed)strlen(num) - 1; // délka čísla tmp[16] = 0; for(i = 0; i < 16; i ++) { if(i / 4 > l) tmp[i] = 0; else { c = num[l - i / 4]; if(c >= '0' && c <= '9') tmp[15 - i] = (((c - '0') >> (i % 4)) & 1)? '1' : '0'; else /*if(c >= 'A' && c <= 'F')*/ tmp[15 - i] = (((c - 'A' + 10) >> (i % 4)) & 1)? '1' : '0'; } } return tmp; } char *Bin_to_Hex(char *num) { char *tmp; int i, l, j; tmp = (char*)malloc(5); l = (signed)strlen(num); // délka čísla tmp[4] = 0; for(i = 0; i < 4; i ++) { tmp[i] = 0; for(j = (3 - i) * 4; j < (3 - i + 1) * 4; j ++) tmp[i] += ((j < l)? (num[l - j - 1] == '1') : 0) << (j - (3 - i) * 4); // načítá čtveřici čísel (i s mocninou dvou) if(tmp[i] < 10) tmp[i] = '0' + tmp[i]; else tmp[i] = 'A' + tmp[i] - 10; // převede do hexa } return tmp; } int Bin_to_Dec(char *num) { int n, i, l; l = (signed)strlen(num); // délka čísla for(i = 0, n = 0; i < l; i ++) n += (num[i] == '1') << (l - i - 1); // převede (easy :-)) return n; } int Hex_to_Dec(char *num) { int n, i, l; l = (signed)strlen(num); // délka čísla for(i = 0, n = 0; i < l; i ++) { if(num[i] >= '0' && num[i] <= '9') n += (num[i] - '0') << ((l - i - 1) * 4); else /*if(num[i] >= 'A' && num[i] <= 'Z')*/ n += (num[i] - 'A' + 10) << ((l - i - 1) * 4); } // převede na dec return n; } void main(int argc, char **argv) { char *hex, *bin, *b_hex, *h_bin; unsigned int i, i_b, i_h; printf("Zadej cislo 0-65535 : "); scanf("%d", &i); hex = Dec_to_Hex(i); bin = Dec_to_Bin(i); b_hex = Bin_to_Hex(bin); h_bin = Hex_to_Bin(hex); i_b = Bin_to_Dec(bin); i_h = Hex_to_Dec(hex); // provede vsechny prevody ... printf("Hex(%d) = %s\n" "Bin(%d) = %s\n" "Hex(%s) = %s\n" "Bin(%s) = %s\n" "Dec(%s) = %d\n" "Dec(%s) = %d\n", i, hex, i, bin, bin, b_hex, hex, h_bin, bin, i_b, hex, i_h); // tiskne výsledky free((void*)hex); free((void*)bin); free((void*)b_hex); free((void*)h_bin); // uvolní paměť getchar(); } 3) - Napište program, vypisující mocniny reálných čísel za použití 16:16 fixed point. // není to tak moc přesné a při velkých číslech to snadno způsobí // přetečení (ale pro grafické algorytmy je to jako dělané :-)) #include <stdio.h> unsigned __int64 Make_FP(float f) { return (unsigned __int64)(f * 65536); // převod na 48:16 fixed point } float Make_Float(unsigned __int64 fp_num) { return (float)((signed)(fp_num)) / 65536; } int Make_Int(unsigned __int64 fp_num) { return (int)(fp_num >> 16); } // funkce na mocniny unsigned __int64 FP_Pow(unsigned __int64 fp_num, int pow) { if(pow == 1) return fp_num; return (fp_num * FP_Pow(fp_num, pow - 1)) >> 16; } void main(int argc, char **argv) { float f; int i; printf("Zadej kladne realne cislo : "); scanf("%f", &f); printf("Zadej kladnou celou mocninu : "); scanf("%d", &i); // přečte data printf("%.2f ^ %d = %.2f (%d)\n", f, i, Make_Float(FP_Pow(Make_FP(f), i)), Make_Int(FP_Pow(Make_FP(f), i))); // tiskne výsledky getchar(); } 4) - Napište program, který zašifruje zadané slovo podle zadaného hesla pomocí xor. (výsledky vypište jako hexa číslice a pak jako text) #include <string.h> #include <stdio.h> void main(int argc, char **argv) { char pwd[256], text[256], crypted[256]; int i; printf("Zadej text : "); scanf("%s", text); printf("Zadej heslo : "); scanf("%s", pwd); // přečte data for(i = 0; i < (signed)strlen(text); i ++) crypted[i] = text[i] ^ pwd[i % strlen(pwd)]; // šifruje pomocí xor - ^ for(i = 0; i < (signed)strlen(text); i ++) printf("0x%X, ", crypted[i]); // tiskne hexa printf("\n%s \n", crypted); // tiskne text getchar(); } === Kapitola 14 === 1) - Zapište do souboru data v binárním a textovém módu a čtěte je v binárním a textovém módu (takže budou čtyři výstupy) Výsledky zobrazte jako hex čísla #include <stdio.h> void Read_Hex(char *filename, char *mode) { char c[1]; FILE *fr; long l; if((fr = fopen(filename, mode)) == NULL) { printf("Soubor nejde otevrit !\n"); return; } fseek(fr, 0, SEEK_END); l = ftell(fr); // najde konec souboru fseek(fr, 0, SEEK_SET); // vrátí se zase na začátek souboru while(ftell(fr) < l) { // přečte celý soubor fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-) printf("0x%X ", ((int)c[0]) & 0xff); // aby to nevypisovalo čísla delší než bajt } // vytiskne obsah printf("\n\n"); fclose(fr); } void Write_Random(char *filename, char *mode) { char data[10] = {0x61, 0x0a, 0x62, 0x0d, 0x63, 0x0a, 0x0d, 0x64, 0x01, 0x0f}; FILE *fw; if((fw = fopen(filename, mode)) == NULL) { printf("Soubor nejde otevrit !\n"); return; } fwrite(data, sizeof(data), 1, fw); // zapíše data fclose(fw); } void main(int argc, char **argv) { Write_Random("Soubor_txt.txt", "w"); Write_Random("Soubor_bin.txt", "wb"); // zapíše binárně a textově printf("Textovy cteny textove :\n"); Read_Hex("Soubor_txt.txt", "r"); printf("Textovy cteny binarne :\n"); Read_Hex("Soubor_txt.txt", "rb"); printf("Binarni cteny textove :\n"); Read_Hex("Soubor_bin.txt", "r"); printf("Binarni cteny binarne :\n"); Read_Hex("Soubor_bin.txt", "rb"); getchar(); } 2) - Máme strukturu : struct Pokus { char a; short b; short c; }; Zapište ji v binárním módu do souboru, potom ji znovu binárně přečtěte a zobrazte výsledek jako hex čísla. Zapište ji napřed celou a potom po částech. #include <stdio.h> void Read_Hex(char *filename, char *mode) { char c[1]; FILE *fr; long l; if((fr = fopen(filename, mode)) == NULL) { printf("Soubor nejde otevrit !\n"); return; } fseek(fr, 0, SEEK_END); l = ftell(fr); // najde konec souboru fseek(fr, 0, SEEK_SET); // vrátí se zase na začátek souboru while(ftell(fr) < l) { // přečte celý soubor fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-) printf("0x%X ", ((int)c[0]) & 0xff); // aby to nevypisovalo čísla delší než bajt } // vytiskne obsah printf("\n\n"); fclose(fr); } struct Pokus { char a; short b; short c; }; void main(int argc, char **argv) { FILE *fw; Pokus p; p.a = 0x12; p.b = 0x3456; p.c = 0x789a; // zapíše binárně a textově fw = fopen("Cely.txt", "w"); fwrite(&p, sizeof(p), 1, fw); fclose(fw); // zapíše celou strukturu fw = fopen("Casti.txt", "w"); fwrite(&p.a, sizeof(char), 1, fw); fwrite(&p.b, sizeof(short), 1, fw); fwrite(&p.c, sizeof(short), 1, fw); fclose(fw); // zapíše celou strukturu printf("Cela :\n"); Read_Hex("Cely.txt", "rb"); printf("Po castech :\n"); Read_Hex("Casti.txt", "rb"); printf("(velikost struktury je 6, velikost casti je 5 (char = 1 + 2 * short = 4))\n"); getchar(); } 3) - Zkuste napsat program, který bude šifrovat soubory. (pomocí xor) Porovnejte výsledky v textovém a binárním módu. // funguje samozřejmě jen binární verze, protože při xorování se vyskytnou // znaky jako 0 a podobně (bylo by potřeba napsat zaměňování těchhle znaků // za něco jako escape sekvence v céčku - pak to půjde třeba i tisknout..) #include <string.h> #include <stdio.h> void Read_Hex(char *filename, char *mode) { char c[1]; FILE *fr; long l; if((fr = fopen(filename, mode)) == NULL) { printf("Soubor nejde otevrit !\n"); return; } fseek(fr, 0, SEEK_END); l = ftell(fr); // najde konec souboru fseek(fr, 0, SEEK_SET); // vrátí se zase na začátek souboru while(ftell(fr) < l) { // přečte celý soubor fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-) printf("0x%X ", ((int)c[0]) & 0xff); // aby to nevypisovalo čísla delší než bajt } // vytiskne obsah printf("\n\n"); fclose(fr); } void Cipher(char *file_src, char *file_dest, char *mode, char *modeb, char *pwd) { FILE *fr, *fw; char c[1]; long l; long i; fw = fopen(file_dest, modeb); if((fr = fopen(file_src, mode)) == NULL) { printf("Soubor nejde otevrit !\n"); return; } fseek(fr, 0, SEEK_END); l = ftell(fr); // najde konec souboru fseek(fr, 0, SEEK_SET); // vrátí se zase na začátek souboru while((i = ftell(fr)) < l) { // přečte celý soubor fread(c, sizeof(c), 1, fr); // dá se použít při čtení statických polí ;-) c[0] ^= pwd[i % (signed)strlen(pwd)]; // heslo se pořád opakuje fwrite(c, sizeof(c), 1, fw); // zapíše } // šifruje fclose(fr); fclose(fw); } void main(int argc, char **argv) { FILE *fw; fw = fopen("Text.txt", "w"); fprintf(fw, "Soubor na zašifrování.\nBla bla bla ...\n0123456789\n"); fclose(fw); // zapíše soubor Cipher("Text.txt", "Bin.txt", "rb", "wb", "heslo"); Cipher("Text.txt", "Txt.txt", "r", "w", "heslo"); // šifruje bin a text (heslo je "heslo") Cipher("Bin.txt", "Bin2.txt", "rb", "wb", "heslo"); Cipher("Txt.txt", "Txt2.txt", "r", "w", "heslo"); // dešifruje printf("Text :\n"); Read_Hex("Txt2.txt", "rb"); printf("Bin :\n"); Read_Hex("Bin2.txt", "rb"); // vypíše výsledky getchar(); }