Súbory alebo "prečítaj mi, čo je na disku".

Všetky programy, ktoré sme doteraz urobili, čítali svoj vstup z klávesnice a výsledky vypisovali na terminál. Pri jednoduchších programoch s tým vystačíme. Ale v prípade, že by sme museli na vstup zadávať päťsto čísel prepísať kapitolu nejakej knižky alebo z klávesnice zadať obrázok, nastali by problémy. A práve pre to, aby sa podobné veci robili ľahšie, ľudia vymysleli súbory.

Čokoľvek si ukladáte na disk alebo disketu, ukladá sa tam v súboroch. A v tejto lekcii sa dozviete niektoré základné finty, ako vaše programy môžu súbory otvárať a čítať z nich alebo do nich zapisovať.

Pre prácu so súbormi používa C-čko štruktúru FILE. Ak chcete nejaký súbor otvoriť, musíte si najprv zadeklarovať premennú typu FILE *. (Načo je tam tá hviezdička sa dozviete v niektorej z ďalších lekcií.) Potom na túto premennú nalepíte nejaký konkrétny súbor z disku. Pri tom nalepovaní musíte povedať, akým spôsobom sa má súbor otvoriť. Sú v podstate tri základné možnosti. Súbor môžete otvoriť na čítanie (v tom prípade už musí na disku existovať), môžete ho otvoriť na zápis (vtedy existovať nemusí, vytvorí sa nový; ak súbor pred tým existoval, tak sa zmaže a nejeden programátor sa potom diví...) a môžete ho otvoriť na zápis na koniec (vtedy sa existujúci súbor nezmaže a môžete k nemu niečo pridať.) Keď je súbor šťastne otvorený, môžete z neho čítať alebo do neho zapisovať funkciami podobnými na tie, ktoré už poznáte. Keď prácu so súborom skončíte, je dobré súbor za sebou zavrieť, aby sa previedla synchronizácia a mohli sa uvolniť systémové zdroje (po slovensky: aby sa to, čo sa má do súboru zapísať, skutočne zapísalo a neostalo trčať v pamäti a aby si systém nemusel pamätať, že tamten súbor je ešte stále otvorený.) V praxi to vyzerá nasledovne:

    FILE *f;
    int c;
    
    f = fopen("pokus.txt","r");
    while ((c = getc(f)) != EOF)
        putchar(c);
    
    fclose(f);
Na začiatku sme deklarovali premennú f typu FILE * a premennú c typu int. Potom sme s pomocou funkcie fopen k premennej f priplácli súbor pokus.txt. Druhý parameter "r" funkcie fopen hovorí, že súbor otvárame na čítanie. Keby sme ho otvárali na zápis, bolo by tam "w" a keby sme ho otvárali na pripájanie, bolo by tam "a".

Potom nasleduje cyklus v ktorom sa opakovane volá funkcia getc(f) -- slúži na to isté ako funkcia getchar() s tým rozdielom, že načíta jeden znak zo súboru priplácnutému k f. Ak sa náhodou už prečítal celý súbor, funkcia vráti hodnotu EOF. (EOF je číslo závislé na operačnom systéme. Väčšinou je to -1.0.13) Takže ten cyklus bude znak po znaku prepisovať celý súbor na obrazovku, až kým nepríde na jeho koniec. Keď cyklus skončí, súbor sa zavrie príkazom fclose(f).

Úloha č.1 Vytvorte si editorom súbor pokus.txt a niečo do neho napíšte. Potom do iného súboru napíšte, skompilujte a spustite uvedený program.

Ak chcete čítať zo súboru priviazanému k f, použijete buď príkaz getc (ako v predošlej ukážke) alebo funkciu fscanf. Funkcia fscanf pracuje rovnako ako funkcia scanf, akutát že ako prvý parameter treba uviesť, z ktorého súboru sa číta. Teda na načítanie celého čísla zo súboru priviazanému k f do premennej i slúži príkaz fscanf(f,"%d",&i).

Na zápis do súboru slúži funkcia putc, ktorá do súboru vloží jeden znak (napr. putc('A',f) -- pozor, tu je prvý parameter znak a až druhý je smerník na súbor.) alebo funkcia fprintf. Táto funguje rovnako ako printf, len jej treba povedať, do ktorého súboru má písať, napr. fprintf(f,"Premenna i ma hodnotu %d.",i)

V nasledujúcej ukážke skopírujeme súbor pokus.txt do súboru kopia.txt a popri tom spočítame, koľkokrát sa v ňom vyskytne písmeno f.

    FILE *fr, *fw;
    int c, pocet = 0;
    
    fr = fopen("pokus.txt","r");
    fw = fopen("kopia.txt","w");
    
    while ((c = getc(fr)) != EOF)
    {
        fprintf(fw,"%c",c);
        if (c == 'f')
            pocet++;
    }
    
    fclose(fr);
    fclose(fw);
    printf("Pismenko f tam bolo %d krat.\n",pocet);

Úloha č.2 Pochopte, skompilujte a vyskúšajte druhú ukážku.

Úloha č.3 Napíšte program, ktorý zo súboru cisla.txt prečíta tri celé čísla a vypíše ich súčet.

Úloha č.4 Napíšte program, ktorý zistí počet riadkov súboru pokus.txt. (Pomôcka: na konci každého riadku sa nachádza znak '\n'.)

Úloha č.5 (povinná pre tých, ktorí majú z písomiek aspoň 10 bodov) Napíšte program, ktorý skopíruje súbor pokus.txt do súboru kopia.txt, ale všetky písmená 'A' pri tom vynechá.

Anino Belan 2003-10-26