15. cvičení

Načítání strukturovaných dat ze souboru

Z terminálu umíme načíst číselné hodnoty pomocí funkce scanf a uložit je do proměnných typu např. int nebo float. Pro načítání číselných dat ze souboru je možné podobným způsobem použít funkci fscanf, ale její použití není vhodné pro čtení strukturovaných souborů – funkce fscanf totiž při načítání čísel ignoruje konce řádků.

Pokud chceme při načítání číselných dat ze souboru kontrolovat strukturu jednotlivých řádků, např. že na každém řádku jsou právě 2 čísla, je potřeba zkombinovat načítání po řádcích a načítání dat z textového řetězce:

Probrané příklady

  1. Načítání strukturovaných dat ze souboru. Načteme data uložená v následujícím formátu:

    N = 4
    1.1     2.0
    0.25    4.0
    -10     -3.14
    1.14    -2.8
    

    První řádek (N = 4) udává počet následujících řádků, ze kterých budeme číst data. Na každém dalším řádku jsou dvě hodnoty, které reprezentují souřadnice \(x\) a \(y\) bodu v rovině. Pro data vytvoříme pole délky N a typu point2d (viz minulé cvičení). Po načtení dat spočítáme obvod a obsah konvexního N-úhelníku daného zadanými body.

    Program by měl vypsat chybu, kdykoliv obsah souboru neodpovídá zadanému formátu.

    Funkce main programu ze cvičení vypadá takto:

    int main()
    {
        FILE* soubor = fopen("data.txt", "r");
        if (soubor == NULL) {
            printf("chyba otevreni souboru\n");
            return 1;
        }
    
        char radek[1000];
        fgetLine(soubor, radek, 1000);
    
        // zpracovat 1. radek
        int N = 0;
        sscanf(radek, "N = %d", &N);
    
        if (N <= 0) {
            printf("chyba: N musi byt kladne.\n");
            fclose(soubor);
            return 1;
        }
    
        // pole pro ukladani bodu ze souboru
        point2d souradnice[N];
    
        for (int i = 0; i < N; i++) {
            fgetLine(soubor, radek, 1000);
            int pocet = sscanf(radek, "%f%f", &souradnice[i].x, &souradnice[i].y);
            if (pocet != 2) {
                printf("chyba: nacteno jen %d hodnot\n", pocet);
                fclose(soubor);
                return 1;
            }
        }
    
        float obvod = obvod_nuhelniku(N, souradnice);
        float obsah = obsah_nuhelniku(N, souradnice);
        printf("Obvod %d-uhelniku je %f.\n", N, obvod);
        printf("Obsah %d-uhelniku je %f.\n", N, obsah);
    
        fclose(soubor);
        return 0;
    }
    

    Chybějící funkce vytvoříte snadno s využitím funkcí z minulého cvičení (viz práce se strukturou point2d).

  2. Načtěte souřadnice bodů ze souboru (stejný formát jako v předchozím příkladu) a seřaďte výsledné pole dle vzdálenosti od počátku.

Domácí úkol

Zadání: dokončete program ze cvičení (výpočet obvodu a obsahu konvexního N-úhelníku a seřazení bodů dle vzdálenosti od počátku).

Výsledný zdrojový soubor (soubor.c) odevzdávejte na mou emailovou adresu do 24. 11. 2019, 24:00 CEST. Pokud narazíte na problém a budete potřebovat poradit, neopisujte od kolegů, ale požádejte mě o radu (mailem, na cvičení nebo na konzultaci). Úkol je vhodné začít vypracovávat co nejdřív, aby se tyto problémy stihly vyřešit před termínem.