Přednáška http://efis.tul.cz/~dana.nejedlova/ Základy programování, Programování I a II Přednáška z jazyka C Probralo se to do snímku "Testování správnosti otevření a uzavření souboru". Cvičení Čtení dat z textového souboru. Teorie, viz kapitola "Return Value" na stránkách http://www.cplusplus.com/reference/cstdio/getc/ http://www.cplusplus.com/reference/cstdio/fscanf/ a mé přednášky z jazyka C. Program přečte první řádek textového souboru. #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; int c; fr = fopen(SOUBOR, "r"); while ((c = getc(fr)) != '\n' && c != EOF) putchar(c); fclose(fr); return 0; } Program přečte první řádek textového souboru. Test na konec je ekvivalentní s předchozím programem dle De Morganových pravidel, viz snímek mých přednášek z jazyka C "Štábní kultura zápisu podmínek". Dle tohoto snímku je lepší řešení v předchozím programu. #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; int c; fr = fopen(SOUBOR, "r"); while (!((c = getc(fr)) == '\n' || c == EOF)) putchar(c); fclose(fr); return 0; } Program, ve kterém je chyba spočívající v tom, že výraz "c = getc(fr)" není uzavřen v závorce. Díky precedenci operátorů se do proměnné c přiřadí výraz "getc(fr) != '\n' && c != EOF" místo návratové hodnoty funkce getc(). Program se přeloží s varováním \main.c|8|warning: suggest parentheses around assignment used as truth value [-Wparentheses]| Když v souboru nebude konec řádku, tak se program zacylí a bude vypisovat znak s kódem 1, což je hodnota true výrazu "getc(fr) != '\n' && c != EOF". #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; int c; fr = fopen(SOUBOR, "r"); while (c = getc(fr) != '\n' && c != EOF) { putchar(c); printf("-'%d' ", c); } fclose(fr); return 0; } Program, ve kterém je chyba spočívající v tom, že dva příkazy, které dle odsazení patří do těla while cyklu, nejsou ve složené závorce {}. Program se přeloží s varováním \main.c|8|warning: this 'while' clause does not guard... [-Wmisleading-indentation]| #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; int c; fr = fopen(SOUBOR, "r"); while ((c = getc(fr)) != '\n' && c != EOF) putchar(c); printf("-%d ", c); fclose(fr); return 0; } Když v souboru nebude konec řádku, tak program vypíše všechny znaky v něm a potom se zacylí a bude vypisovat znak s kódem 255, což je hodnota výrazu "getc(fr)", když se čtení souboru dostane na konec, tedy konstanta EOF interpertovaná jako neznaménkové číslo. Je to zdůvodnění, proč nesmí být proměnná pro načítání znaku ze souboru typu char, viz snímek mých přednášek z jazyka C "Testování konce souboru pomocí symbolické konstanty EOF". #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; unsigned char c; /* Zacykli se. */ fr = fopen(SOUBOR, "r"); while ((c = getc(fr)) != '\n' && c != EOF) { putchar(c); printf("-'%d' ", c); } fclose(fr); return 0; } Program vypíše všechny znaky (na všech řádcích) v souboru. #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; int c; fr = fopen(SOUBOR, "r"); while ((c = getc(fr)) != EOF) { putchar(c); } fclose(fr); return 0; } Program vypíše všechna celá čísla v souboru. Když bude v souboru i něco jiného než celé číslo nebo bílý znak (https://en.wikipedia.org/wiki/Whitespace_character), tak se program zacyklí, protože se funkce fscanf() nebude posouvat ve čtení dál. Viz "Program s volbou ve formě čísla s opakováním, který se zacyklí, když nezadáme číslo." v souboru "7.txt". #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; int c; fr = fopen(SOUBOR, "r"); while (fscanf(fr, "%d", &c) != EOF) { printf("%d\n", c); } fclose(fr); return 0; } Program vypíše všechna celá čísla v souboru i nečíselné znaky. Návratová hodnota funkce fscanf() se porovnává s hodnotou 1, viz snímek mých přednášek z jazyka C "Test zda jsou v souboru data". Pro test na konec souboru je použita funkce feof(), viz snímek mých přednášek z jazyka C "Testování konce souboru pomocí funkce feof()". #include #define SOUBOR "vstup.txt" int main(void) { FILE *fr; int c; fr = fopen(SOUBOR, "r"); do { if (fscanf(fr, "%d", &c) == 1) { printf("%d\n", c); } else { putchar(getc(fr)); } } while (!feof(fr)); fclose(fr); return 0; }