13. cvičení

Procvičování práce se soubory a textovými řetězci.

Probrané příklady

  1. Dokončení programu z minulého cvičení – program přečte text ze souboru a slovo z terminálu, vyhledá zadané slovo v textu, přepíše všechny výskyty tohoto slova v textu velkými písmeny a výsledný řetězec zapíše do jiného souboru.

    #include <stdio.h>
    #include <stdbool.h>
    #include <string.h>
    #include <ctype.h>
    
    // funkce pro nacteni jednoho radku textu z terminalu
    bool getLine(char* string, int maxDelka)
    {
        for (int i = 0; i < maxDelka; i++) {
            // precti znak z terminalu
            int znak = getchar();
    
            // zkontroluj, jestli neni konec vstupu
            if (znak != EOF && znak != '\n')
                string[i] = znak;
            else {
                // konec vstupu - ukonci string a prerus cyklus
                string[i] = '\0';
                return true;
            }
        }
    
        // v cyklu jsme nedosli ke znaku EOF ani k '\n' - vstup je delsi nez (maxDelka - 1)
        // (vypisujeme maxDelka - 1, protoze posledni znak musi byt '\0', ktery ale uzivatel nezadava)
        printf("Chyba: vstup je delsi nez maximalni povolena delka %d znaku.\n", maxDelka - 1);
        return false;
    }
    
    // funkce pro nacteni jednoho radku textu ze souboru
    bool fgetLine(FILE* soubor, char* string, int maxDelka)
    {
        for (int i = 0; i < maxDelka; i++) {
            // precti znak z terminalu
            int znak = fgetc(soubor);
    
            // kontrola jestli nedoslo k chybe cteni
            if (ferror(soubor)) {
                printf("Chyba: neslo precist cely radek\n");
                return false;
            }
    
            // zkontroluj, jestli neni konec vstupu
            if (znak != EOF && znak != '\n')
                string[i] = znak;
            else {
                // konec vstupu - ukonci string a prerus cyklus
                string[i] = '\0';
                return true;
            }
        }
    
        // v cyklu jsme nedosli ke znaku EOF ani k '\n' - radek je delsi nez (maxDelka - 1)
        // (vypisujeme maxDelka - 1, protoze posledni znak musi byt '\0', ktery ale uzivatel nezadava)
        printf("Chyba: radek je delsi nez maximalni povolena delka %d znaku.\n", maxDelka - 1);
        return false;
    }
    
    // funkce pro zpracovani jednoho radku - nalezeni slova a nahrada velkymi pismeny
    void zpracuj_radek(char* string, char* slovo)
    {
        int delka_slova = strlen(slovo);
        char* pozice = strstr(string, slovo);
        while (pozice != NULL) {
            // kontrola celeho slova
            if ( (pozice == string || isspace(*(pozice - 1))) &&
                 (pozice[delka_slova] == '\0' || isspace(pozice[delka_slova])) )
            {
                // prepis velkymi pismeny
                for (int i = 0; i < delka_slova; i++)
                    pozice[i] = toupper(pozice[i]);
            }
            // najit dalsi slovo - zaciname od prvniho znaku za nalezenym slovem
            pozice = strstr(pozice + delka_slova, slovo);
        }
    }
    
    int main()
    {
        FILE* vstup = fopen("vstup.txt", "r");
        if (vstup == NULL) {
            printf("chyba otevreni souboru\n");
            return 1;
        }
        FILE* vystup = fopen("vystup.txt", "w");
        if (vystup == NULL) {
            printf("chyba otevreni souboru\n");
            return 1;
        }
    
        // nacist slovo z terminalu
        char slovo[100];
        printf("Zadej slovo: ");
        getLine(slovo, 100);
    
        char radek[1000];
        while (!feof(vstup)) {
            // nacist radek
            fgetLine(vstup, radek, 1000);
            // zpracovat radek
            zpracuj_radek(radek, slovo);
            // zapis radek do vystupniho souboru
            fprintf(vystup, "%s\n", radek);
        }
    
        fclose(vstup);
        fclose(vystup);
    
        return 0;
    }
    
  2. Vytvoření histogramu pro výskyt znaků v daném souboru.

    #include <stdio.h>
    
    int main()
    {
        FILE* soubor = fopen("vstup.txt", "r");
        if (soubor == NULL) {
            printf("chyba otevreni souboru\n");
            return 1;
        }
    
        // tabulka (histogram) poctu vyskytu pro kazdy znak
        int pocty_vyskytu[256];
        for (int i = 0; i < 256; i++)
            pocty_vyskytu[i] = 0;
    
        // dokud nedojdu na konec souboru
        while (!feof(soubor)) {
            // nacist znak
            int znak = fgetc(soubor);
            // pricist 1 v poli
            if (znak != EOF)
                pocty_vyskytu[znak]++;
        }
    
        fclose(soubor);
    
        // najit nejcastejsi znak
        int max = 0;
        for (int i = 0; i < 256; i++) {
            if (pocty_vyskytu[i] > pocty_vyskytu[max]) {
                max = i;
            }
        }
        printf("Nejcastejsi znak je '%c', pocet vyskytu: %d\n", max, pocty_vyskytu[max]);
    
        return 0;
    }