Vydělávej až 160.000 Kč měsíčně! Akreditované rekvalifikační kurzy s garancí práce od 0 Kč. Více informací.
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.

2. diel - Práca s textovými súbormi (txt) v jazyku C

V minulej lekcii, Úvod do práce so súbormi v jazyku C , sme si urobili úvod do práce so súbormi. V dnešnom C tutoriálu sa naučíme pracovať s textovými súbormi, ktoré sú najjednoduchšie a tiež je asi budeme využívať najčastejšie. Do textových súborov zapisujeme alebo je čítame po riadkoch. Možno je samozrejme čítať / zapisovať i po znakoch, ale riadkový prístup je určite ľudskejší. K zápisu do súboru budeme používať funkciu fprintf () a na čítanie fscanf (). Dvojica funkcií funguje úplne rovnako ako printf () a scanf (), ktoré pracovali so štandardným vstupom / výstupom (konzol). Tieto funkcie však pracujú so súborom. Odkaz na súbor odovzdáme vždy ako prvý parameter funkcie.

Otvorenie súboru

Predtým, než sa súborom začneme pracovať, musíme ho otvoriť. K tomu slúži funkcia fopen (). Pri otváraní súboru špecifikujeme mód, pre ktorý súbor otvárame. Najčastejšie je to "w" (zápis), "r" (čítanie) alebo "a" (pripisovania).

Zatvorenie súboru

Po dokončení práce so súborom ho treba zatvoriť. Asi by ste uhádli, že na to slúži funkcia fclose (). Ak by sme súbor zabudli zavrieť, chápal by operačný systém ako že s ním stále pracujeme. Ostatné programy by ho nemohli používať a tiež by sme zbytočne plytvali zdrojmi, pretože operačný systém má na počet naraz otvorených súborov väčšinou nejaké limity. V neposlednom rade by sme si mali povedať, že práca so súbormi používa tzv. Buffer. Zapisovať totiž znak po znaku by disk veľmi vytížilo, preto sa čaká, až sa naplní určitá vyrovnávaciu pamäť, ktorá sa potom naraz na disk zapíše a tým sa ušetrí prístupy k disku. Keby sme zabudli zavolať fclose (), mohol by vo vyrovnávacej pamäti zostať ešte nejaký text, ktorý by sa do súboru nedopsal.

Zápis do súboru

Uveďme si konečne príklad a to vytvorenie jednoduchého textového súboru s listom. Čoskoro si ho vysvetlíme:

int main(int argc, char** argv) {
    FILE * p_soubor = fopen("dopis.txt", "w");
    if (p_soubor == NULL)
    {
        printf("Soubor se nepodařilo otevřít pro zápis, zkontrolujte prosím oprávnění.");
        return 1;
    }

    fprintf(p_soubor, "Drahá Brynn,\n");
    fprintf(p_soubor, "opatruj se, Malcolm unikl a jistě si pro mne brzy přijde jako pro prvního.\n");
    fprintf(p_soubor, "Musíš navést Brandona, dovést ho k amuletu, klíčem k zaříkávadlu by možná\n");
    fprintf(p_soubor, "mohla být levandulová růže.\n\n");
    fprintf(p_soubor, "Kallak\n");

    if (fclose(p_soubor) == EOF)
    {
        printf("Soubor se nepodařilo uzavřít.");
        return 1;
    }

    return (EXIT_SUCCESS);
}

Na začiatku zavoláme funkciu fopen (), ktoré oznámime, že chceme otvoriť súbor dopis.txt v móde pre zápis. Ak súbor neexistuje, bude vytvorený. Ak už existuje, bude prepísaný! Funkcia vracia ukazovateľ na štruktúru typu FILE. Práve cez tento ukazovateľ budeme so súborom ďalej pracovať a preto si ho uložíme.

Súbor sa nemusí podariť otvoriť a to hlavne vtedy, keď k nemu nemá program prístup. Stane sa tak, keď program napr. Spustíme z disku CD, kam sa nedá zapisovať, alebo keď ho spustíme napr. Priamo na disku C (mimo užívateľské zložky ako sú dokumenty alebo plocha, kam máme povolené zapisovať). Pri tejto situácii vráti NULL (teda prázdny ukazovateľ) a na túto hodnotu by sme mali reagovať.

Prostredná časť programu je triviálne, iba zapisujeme do súboru riadky textu pomocou fprintf (). Samozrejme by sme mohli zapisovať napr. Aj premenné a to takto:

int hlasitost = 100;
fprintf(p_soubor, "hlasitost=%d", hlasitost);

Rovnako, ako sa nemusí podariť otvorenie súboru, nemusí sa podariť ani jeho uzavretie. Funkcia fclose () v tomto prípade vráti hodnotu EOF (ako End Of File).

Keď aplikáciu spustíme, vytvorí sa v aktuálnej zložke s programom súbor dopis.txt s nasledujúcim obsahom:

Vytvorenie textového súboru v jazyku C - Práca so súbormi v jazyku C

Čítanie zo súboru

Čítanie zo súboru je veľmi podobné. Napíšeme si opačnú aplikáciu, ktorá list načíta a vypíše na obrazovku. Budeme predpokladať, že nevieme, koľko má riadkov a preto si ukážeme ako načítať všetky riadky zo súboru.

int main(int argc, char** argv) {
    FILE * p_soubor = fopen("dopis.txt", "r");
    if (p_soubor == NULL)
    {
        printf("Soubor se nepodařilo otevřít pro čtení, zkontrolujte prosím zda existuje.");
        return 1;
    }

    char buffer[1024];
    while (fscanf(p_soubor, " %1023[^\n]", buffer) != EOF)
    {
        printf("%s\n", buffer);
    }

    if (fclose(p_soubor) == EOF)
    {
        printf("Soubor se nepodařilo uzavřít.");
        return 1;
    }

    return (EXIT_SUCCESS);
}

Otvorenie súboru je rovnaké až na zámenu módu z "w" (write) na "r" (read). Teraz budeme potrebovať pomocnú premennú, tzv. Buffer, do ktorého nám bude fscanf () riadku ukladať. Buffer sa robí dostatočne dlhý, väčšinou 1024 znakov. Samotné čítanie riadky je umiestnené vo while cyklu a pokračuje až kým fscanf () nevráti hodnotu EOF. Tá signalizuje, že sme už dosiahli konca súboru. Formátovací reťazec je potrebné upraviť, inak by sa skenovanie zastavovalo o biele znaky (medzery) a my nechceme, aby sa zastavovalo len na konci riadkov (\ n) a my tak čítali naraz celé riadky. Načítanú riadku z bufferu vypíšeme a pokračujeme znova. Na konci súbor uzavrieme.

výsledok:

c_soubory_cteni
Drahá Brynn,
opatruj se, Malcolm unikl a jistě si pro mne brzy přijde jako pro prvního.
Musíš navést Brandona, dovést ho k amuletu, klíčem k zaříkávadlu by možná
mohla být levandulová růže.
Kallak

Funkcia fscanf () má bohužiaľ tú vlastnosť, že prehltne prázdne riadky v súbore a my o nich ani nebudeme vedieť. Niekedy nás to netrápi, ale niekedy bu nám to mohlo vadiť. Preto sa pre čítanie zo súboru niekedy používa funkcie fgets (), ktorá načíta celý riadok až do konca. Aby sme to nemali moc jednoduché, vracia funkcia riadok aj s jeho ukončením, teda so znakom \ n. Ten nám niekedy nevadí (napr. Tu), ale niekedy by sme ho museli odstraňovať. Na použitie fgets () by sa while cyklus zmenil na nasledujúce podobu:

while (fgets(buffer, sizeof(buffer), p_soubor) != NULL)
{
    printf("%s", buffer);
}

výsledok:

c_soubory_cteni
Drahá Brynn,
opatruj se, Malcolm unikl a jistě si pro mne brzy přijde jako pro prvního.
Musíš navést Brandona, dovést ho k amuletu, klíčem k zaříkávadlu by možná
mohla být levandulová růže.

Kallak

Za zmienku stojí, že k funkcii fgets () existuje aj funkcia fputs (), ktorá do súboru zapíše celú riadku. Jej výhodou je, že za ňu automaticky dosadí \ na my ho už nemusíme pripájať. Možno vás napadlo, či neexistujú aj funkcia gets () a puts () pre štandardný vstup a výstup. Áno, môžeme ich používať namiesto printf () a scanf ().

Pripísanie k súboru

Na koniec si ešte ukážme, ako k existujúcemu súboru niečo pripísať. Pretože kód spočíva v podstate len v zámene mód "w" za "a" (append), kód si ani nemusíme vysvetľovať:

int main(int argc, char** argv) {
    // Otevření souboru pro připsání
    FILE * p_soubor = fopen("dopis.txt", "a");
    if (p_soubor == NULL)
    {
        printf("Soubor se nepodařilo otevřít pro připsání, zkontrolujte prosím oprávnění.");
        return 1;
    }

    // Zápis řádek do souboru
    fprintf(p_soubor, "\nPS: Vyžádej pomoc od Darma a Zanthie pro vybudování sil amuletu.\n");

    // Uzavření souboru
    if (fclose(p_soubor) == EOF)
    {
        printf("Soubor se nepodařilo uzavřít.");
        return 1;
    }

    return (EXIT_SUCCESS);
}

A keď si otvoríme súbor v textovom editore:

Pripísanie do textového súboru v jazyku C - Práca so súbormi v jazyku C

Pokročilejšie práce s textovými súbormi (najmä parsovanie formáte CSV) je ukázaná v článkoch Evidencia osôb v jazyku C - Zadávanie a ukladanie osôb do CSV a Evidencia osôb v jazyku C - Načítanie a vyhľadávanie osôb.

V budúcej lekcii, Binárne súbory a neformátovaný text , na nás čakajú binárne súbory.


 

Mal si s čímkoľvek problém? Stiahni si vzorovú aplikáciu nižšie a porovnaj ju so svojím projektom, chybu tak ľahko nájdeš.

Stiahnuť

Stiahnutím nasledujúceho súboru súhlasíš s licenčnými podmienkami

Stiahnuté 140x (108.97 kB)
Aplikácia je vrátane zdrojových kódov v jazyku C

 

Predchádzajúci článok
Úvod do práce so súbormi v jazyku C
Všetky články v sekcii
Práca so súbormi v jazyku C
Preskočiť článok
(neodporúčame)
Binárne súbory a neformátovaný text
Článok pre vás napísal David Hartinger
Avatar
Užívateľské hodnotenie:
Ešte nikto nehodnotil, buď prvý!
David je zakladatelem ITnetwork a programování se profesionálně věnuje 15 let. Má rád Nirvanu, nemovitosti a svobodu podnikání.
Unicorn university David sa informačné technológie naučil na Unicorn University - prestížnej súkromnej vysokej škole IT a ekonómie.
Aktivity