11b Další příklady operací vstupu a výstupu (úvod viz 10) V souboru budu mít uloženo:....... ahoj - čtu tečky pomocí c = getc(fr) až po 'a', ale potom volám funkci, která má zpracovat celé slovo ahoj a nepočítá s tím, že už bylo "vyčteno" - vrátíme znak do vstup. bufferu: ungetc(c, fr) - když se to povede - funkce vrátí jako výsledek vrácený znak (tj. 'a') jinak vrací EOF. Př.: čte znaky a tiskne je na obrazovku (po jednom) int main() FILE *fr int c fr = fopen("text.txt", "r") if(fr == NULL) printf("soubor nejde otevrit!\n") getchar() //cekani na stisk klavesy return(1) /* cteni a tisk souboru text.txt */ while((c = getc(fr))!= EOF) putchar(c) if (fclose(fr) == EOF) printf("soubor text.txt se nepodarilo uzavrit\n") return
while (!kbhit()) return (0) //cekani na stisk klavesy Čtení znaku s testem konce souboru, lze také takto: /* cteni a tisk souboru text.txt */ while(!feof(fr)) c = getc(fr) putchar(c) Př.: Program čte celá čísla z textového souboru (formátovaně) a zapisuje do jiného souboru int main() FILE *fr, *fw int a, b fr = fopen("prvni.txt", "r") // otevřeme pro čtení fw = fopen("druhy.txt", "w") // otevřeme pro zápis if(fr == NULL fw == NULL) printf("soubor nejde otevrit!\n") /* před koncem programu musíme uzavřít všechny soubory */ if(fr!= NULL) fclose(fr) if(fw!= NULL) fclose(fw) while(!kbhit()) return (1)
// formátovaně čtu z fr(předp. celé_číslo celé_číslo) fscanf(fr, "%d %d", &a, &b) // formátovně ukládám do souboru fw (formátovaně neboť // tisknu celé_číslo + celé_číslo = celé_číslo) fprintf(fw, "%d + %d = %d\n", a, b, a + b) fclose(fr) fclose(fw) while(!kbhit()) return (0) Kompletní varianta předešlého příkladu: #include <stdio.h> int main(void) FILE *fr, *fw int a, b fr = fopen("prvni.txt", "r") // otevřeme pro čtení fw = fopen("druhy.txt", "w") // otevřeme pro zápis if(fr == NULL fw == NULL) printf("soubor nejde otevrit!\n") /* před koncem programu musíme uzavřít všechny soubory */ if(fr!= NULL) fclose(fr) if(fw!= NULL) fclose(fw) while(!kbhit()) return (1)
while (1) // formátovaně čtu z fr(předp. celé_číslo celé_číslo) fscanf(fr, "%d %d", &a, &b) // formátovně ukládám do souboru fw (formátovaně neboť tisknu celé_číslo + celé_číslo = celé_číslo) fprintf(fw, "%d + %d = %d\n", a, b, a + b) // pro kontrolu tisknu tez na obrazovku printf("%d + %d = %d\n", a, b, a + b) // jsem-li na konci souboru fr, opustím cyklus a už netisknu if(feof(fr)) break // konec cyklu while if (fclose(fr) == EOF) printf("soubor prvni.txt se nepodarilo uzavrit\n") return if (fclose(fw) == EOF) printf("soubor druhy.txt se nepodarilo uzavrit\n") return else printf("soubor s vysledky (druhy.txt) byl uspesne vytvoren\n") while(!kbhit()) return (0)
Př.: Kopírování souboru s ošetřením otevírání a uzavíraní souboru #include <stdio.h> /* Čekání volá funkci operačního systému, která se liší v různých systémech. Proto si připravím makro CEKEJ a na jiném systému to změním pouze zde a nemusím hledat na jakých řádcích jsem čekání použil. */ #define CEKEJ system("pause") main() FILE *fr, *fw int c fr = fopen("orig.txt", "r") if (fr == NULL) printf("soubor ORIG.TXT se nepodarilo otevrit\n") CEKEJ return /* ukonceni programu */ if ((fw = fopen("kopie.txt", "w")) == NULL) printf("soubor KOPIE.TXT se nepodarilo otevrit\n") CEKEJ return /* ukonceni programu */ while ((c = getc(fr))!= EOF) putc(c, fw) if (fclose(fr) == EOF) printf("soubor ORIG.TXT se nepodarilo uzavrit\n") CEKEJ return if (fclose(fw) == EOF) printf("soubor KOPIE.TXT se nepodarilo uzavrit\n") CEKEJ return CEKEJ
Pozn. k souborům obecně - jak zadat název soub. a cestu z klávesnice char rezim[4], cesta[51] /* vzdy kolikn chci + 1 na '\0' */ scanf("%3s", rezim) /* ctu 2 znaky z klav.,u retezcu se nedela & */ scanf("%50s", cesta) f = fopen(cesta, rezim) Práce s binárními soubory FILE *fr, *fw fr = fopen("d:\\pozdravy\\nazdar.bmp", "rb") fw = fopen("d:\\pozdravy\\nazdar2.bmp", "wb") Textové vs. binární soubory 65535 - v textovém souboru 5 byte - neboť 5 znaků 65535 - v binárním souboru 2 byte - binárně: 65535 D = 1111111111111111 B - textové se snadno upravují v editoru - s binárními je rychlejší práce (ale trochu složitější) int fread(char *kam, int velikost, int pocet, FILE *soubor) kde: kam pole do kterého načítám ze souboru velikost kolik byte má jedna jednotka dat (hodnota, např. 1 pro char, 8 pro double atp.) pocet kolik hodnot chci načíst najednou (dáno velikostí kam)
int fwrite(char *odkud, int velikost, int pocet, FILE *soubor) - posun na libovolné místo v bin souboru int fseek(file *soubor, long posun, int odkud) - odkud má jednu z hodnot: SEEK_SET - od začátku souboru SEEK_CUR - od aktuální pozice-kde jsem byl naposled SEEK_END - od konce souboru - je-li posun úspěšný vrací 0, jinak nenul. hodnotu long ftell(file *soubor) - vrací kolik byte jsme od začátku souboru #include <stdio.h> #define BUFF_SIZE 512 int main() FILE *fr int nacteno[buff_size] int kolikprecteno, i fr = fopen("prezentace.pptx", "rb") if(fr == NULL) printf("soubor nejde otevrit!\n") getchar() //cekani na stisk klavesy
return(1) while (getchar()!= '\n') printf("\n") /* cteni a tisk z binarniho souboru */ while(!feof(fr)) kolikprecteno = fread(nacteno, sizeof(int), BUFF_SIZE, fr) for(i = 0 i < kolikprecteno i++) printf("%d\n", nacteno[i]) printf("--------pozice v souboru je %d -------- \n", ftell(fr)) if (kbhit()) printf("cteni souboru ukonceno uzivatelem...") break if (fclose(fr) == EOF) printf("soubor text.txt se nepodarilo uzavrit\n") return printf("\nkonec cteni souboru...\n") while (getchar()!= '\n') while (!kbhit()) //cekani na stisk klavesy return (0)