Fotografický magazín "iZIN IDIF" každý týden ve Vašem e-mailu.
Co nového ve světě fotografie!
Zadejte Vaši e-mailovou adresu:
Kamarád fotí rád?
Přihlas ho k odběru fotomagazínu!
Zadejte e-mailovou adresu kamaráda:
C/C++
Učíme se C (20. díl) - Práce se soubory II.
23. února 2001, 00.00 | Dnes si uvedeme funkce pro čtení a zápis do souboru (především pak blokové
vstupně-výstupní funkce) a podporu nesekvenčního přístupu k souboru.
Funkce pro zápis do souboru
Pro zápis do souboru nám poslouží funkce putc(), fprintf(), a fputs(), jejichž deklarace jsou zde:
int putc(int c, FILE *file); int fprintf(FILE *file, char *formát, ...); int fputs (char *string, FILE *file);
Asi nemá cenu dlouho se u těchto funkcí zdržovat, neboť jejich chování je podobné jim příbuzným funkcím putchar, printf a puts, které slouží pro zápis na standardní výstup, a které jsme již probrali v desátém dílu tohoto seriálu. Je nutné pouze říct, že po provedení některé z těchto funkcí se file-pointer posune v souboru za poslední zapsaný byte. To ostatně platí i pro všechny další funkce zapisující do souboru. Teď se ale raději podíváme na funkci pro blokový zápis.
Funkce fwrite()
int fwrite(void *ptr, int size, int n, FILE *file);
Funkce fwrite() zapíše do proudu file n položek přečtených z paměti označené ukazatelem ptr. Velikost jedné položky v bytech udává parametr size, takže celkový počet zapisovaných bytů je roven size*n. Funkce fwrite() vrací počet úspěšně zapsaných položek, nikoli bytů!
Příklad použití funkce fwrite se nachází níže, v části věnované funkci fread.
Funkce pro čtení ze souboru
Obdobně jako při zápisu do souboru, i pro čtení jsou definovány podobné funkce, jaké jsme používali při čtení ze standardního vstupu:
int getc(FILE *file); int fscanf(FILE *file, char *formát, ...); char *fgets(char *string, int n, FILE *file);
Zajímavá je především funkce fgets, která oproti příbuzné funkci gets umožňuje definovat maximální počet přečtených znaků. Protože standardní vstup i výstup jsou také datové proudy (jsou automaticky inicializované při spuštění programu) můžeme pro čtení ze standardního vstupu použít, namísto funkce gets, bezpečnou fgets:
|
I funkce čtoucí ze souboru posouvají file-pointer, a to za poslední přečtený znak souboru.
Funkce fread()
Pro blokové čtení ze souboru nám poslouží funkce fread():
int fread(void *ptr, int size, int n, FILE *file);
Z datového proudu file přečte n položek o velikosti size bytů a uloží je do paměti označené ukazatelem ptr. Návratovou hodnotou je počet skutečně přečtených položek.
V následujícím příkladu uložíme do souboru data.bin pole struktur ar1 a v jiné části programu tento soubor načteme do pole ar2. Pro jednoduchost nebudeme ošetřovat chybové stavy (soubor se nepodařilo otevřít, nepodařilo se zapsat/přečíst potřebný počet položek):
|
Nesekvenční přístup
Na souborové datové proudy lze použít tzv. nesekvenční (náhodný) přístup, což znamená, že nemusíme číst jeden byte za druhým tak, jak jsou v souboru uloženy, ale můžeme „skákat“ (přesunovat file-pointer) na libovolnou pozici v souboru. K tomuto účelu slouží funkce fseek().
int fseek (FILE *file, long offset, int mode);
Funkce přesune file-pointer na pozici vzdálenou offset bytů od pozice mode, přičemž za parametr mode je možné zvolit jednu z následujících konstant:
SEEK_SET | Začátek souboru |
SEEK_CUR | Aktuální pozice v souboru |
SEEK_END | Konec souboru |
Př:
zápis | file-pointer se přesune na... |
fseek(f, 0, SEEK_SET); |
začátek souboru |
fseek(f, 0, SEEK_END); |
konec souboru |
fseek(f, -10, SEEK_CUR); |
pozici o deset bytů zpět od aktualní pozice |
fseek(f, 10, SEEK_SET); |
jedenactý byte souboru |
Je-li soubor, se kterým pracujeme, otevřen v módu pro čtení i zápis, musíme mezi každou operací čtení a operací zápisu volat funkci fseek(). Tato nepříjemnost je nutná kvůli synchronizaci file-pointerů, které jinak nemusí být správně nastaveny. Funkci fseek() ale můžeme volat i s nulovým posunem. Tento postup si ukážeme na příkladu, ve kterém ve streamu f převedeme všechna malá písmena na velká.
|
Pro zjednodušení bychom v uvedeném příkladu ještě mohli použít makra islower() (pro detekci znaku malého písmena) a toupper() (pro převod na velké písmeno).
Chceme-li zjistit, jaká je aktuální pozice file-pointeru v souboru, můžeme použít funkci ftell(), která tuto pozici vrací jako svou návratovou hodnotu.
long ftell (FILE *file);
Obsah seriálu (více o seriálu):
- Učíme se C (1. díl)
- Učíme se C (2. díl)
- Učíme se C (3.díl)
- Učíme se C (4. díl)
- Učíme se C (5.díl)
- Učíme se C (6.díl)
- Učíme se C (7.díl)
- Učíme se C (8.díl)
- Učíme se C (9.díl) - Řetězce
- Učíme se C (10.díl) - Vstupně výstupní funkce
- Učíme se C (11.díl) - Formátovaný výstup
- Učíme se C (12.díl) - Formátový specifikátor
- Učíme se C (13.díl)
- Učíme se C (14.díl) - Vícerozměrná pole
- Učíme se C (15.díl) - Ukazatele
- Učíme se C (16.díl) - Modifikátory paměťové třídy
- Učíme se C (17.díl) - Pole a ukazatel
- Učíme se C (18. díl) - Dynamická alokace paměti
- Učíme se C (19. díl) - Práce se soubory I.
- Učíme se C (20. díl) - Práce se soubory II.
- Učíme se C (21. díl) - Parametry funkce main()
- Učíme se C (22. díl) - Ukazatele na funkce
- Učíme se C (23. díl) - Složité deklarace a definice
- Učíme se C (24. díl) - Funkce s proměnným počtem parametrů
- Učíme se C (25. díl) - Bitové operátory a bitové pole
- Učíme se C (26. díl) - Datové typy enum a union
- Učíme se C (27. díl - závěr) - Programové moduly
Diskuse k článku
-
25. listopadu 2012
-
30. srpna 2002
-
10. října 2002
-
4. listopadu 2002
-
12. září 2002
-
25. listopadu 2012
-
28. července 1998
-
31. července 1998
-
28. srpna 1998
-
6. prosince 2000
-
27. prosince 2007
-
4. května 2007