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]; scanf("%3s", rezim); /* ctu scanf("%50s", cesta); f = fopen(cesta, rezim);
/* vzdy kolikn chci + 1
na '\0' */
2 znaky z klav.,u retezcu se nedela & */
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ě: 65535D = 1111111111111111B - 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); }