1.1
File kezelés
A C nyelvben aza datállományokat tartalmuk alapján két
csoportra oszthatjuk, szöveges és bináris állományokra. A szöveges állományok
olvasható információt tartalmaznak. Sorokból épülnek fel, minden sor végét a
CR/LF karakterpár zárja.A bináris állományok byte-okból felépülő adtahalmazt
jelentenek. A szöveges állomány minden esetben földolgozható, mint bináris
állomány, de ez fordítva már nem igaz.
Szöveges állományokban is lehet számokat tárolni. Ebben az
esetben a számok, mint karakterek fogan tárolódni. Ha például egy négy jegyű
számot szöveges állományban tárolunk, akkor négy byte-nyi helyet foglal el, ha
azonban egy bináris állományba tesszük le, akkor csak 2 byte kell.
(Természetesen csak akkor, ha int típusú volt)
1.1.1
File előkészítése, lezárása
A file kezeléshez tartozó függvények az stdio.h deklarációs
állományban vannak leírva. Minden file-hoz hozzá kell rendelni egy FILE típusú
muatatót, mely a memóriában a file jellemzőire mutat[1]. Ennek
formája:
FILE *fp;
Ez után következhet a file megnyitása:
fp=fopen(”A:\SZOVEG\NEV.TXT”név”,”mód”);
Az fp mutató értéke
NULL, ha az állomány
megnyitása sikertelen volt. A fizikai file névben teljes elérési útvonalat is
megadhatunk, ebben az esetben azonban ügyelni kell a \ jel használatára:
”A:\SZOVEG\NEV.TXT” helyett ”A:\\SZOVEG\\NEV.TXT”[2]
A mód paraméter azt jelenti, hogy milyen műveleteket akarunk
végezni az állománnyal.
Mód |
Leírás |
r (+) |
Létező file
megynyitása olvasásra. File
mutató a file elejére áll. |
w (+) |
Új file
megnyitása írásra. Létező file
esetén annak tartalma elvész. .
File mutató a file elejére áll. |
a (+) |
File megnyitása
hozzáírásra. Nyitás után a file
mutatóa file végére áll. Ha a
file nem létezik, akkor az fopen
létrehozza |
Mindegyik mód jellemző kiegészíthető egy + paraméterrel, ez
miden esetben azt jelenti, hogy az állományt olvashatjuk és írhatjuk is. A mód
sztringben szoktuk még megadni, hogy milyen állománnyal dolgozunk. t szöveges, b
bináris állományt jelent.
Nézzünk egy konkrét példát, melyben egy szöveges állományt
megnyitunk írásra és olvasásra:
FILE *fp;
fp=fopen(”A:\\SZOVEG\\NEV.TXT”,”r+t”);
if (fp==NULL)
{
printf(”Sikertelen file nyitás!”);
return –1;
}
A file nyitást gyakra szokták az
if-en
belülre helyezni. Ekkor a szintaktikája a következő:
if (!(fp=fopen(”A:\\SZOVEG\\NEV.TXT”,”r+t”)))
{
printf(”Sikertelen file nyitás!”);
return –1;
}
Ha a file-on elvégeztük a megfelelő műveleteket akkor le kell
zárni. Ezt az
fclose(fp) függvényhívás valósítja
meg. Amennyiben egy filban írási műveletekt is végeztünk lezárás előtt célszerű
az fflush(fp) függvényhívás, ez az átmeneti pufferek tartalmát kiírja az
állományba, ha még nem történt volna meg.
1.1.2
Szöveges állományok
Szöveges állományokkal kapcsolatban leggyakrabban alkalmazott
függvényeket az alábbi táblázatban foglajuk össze. Minden esetben a
FILE *fp;
char ch,string[]=”Kiírandó szöveg”;
char sz[20];
definíciókat használjuk
Függvény |
Leírás |
ch=fgetc(fp) |
Beolvas egy karaktert a
file-ból |
fputc(ch,fp) |
Kiír egy karaktert a file-ba |
fgets(sz,strlen(string)+1,fp) |
Az sz változóba beolvas egy
sztringet |
fputs(string,fp) |
A string változó tartalmát
kiírja a file-ba |
fscanf(fp,”konv”,&valt) |
Hasonló a scanf-hez, eltérés az
első paraméterben |
fprintf(fp,”konv”,valt |
Hasonló a printf-hez, eltérés
az első paraméterben |
Az alábbiakban két egyszerű programot mutatunk be a szöveges
állományok kezelésére:
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
main()
{
char c;
FILE *fp;
int i;
clrscr();
if
(!(fp=fopen("A:\\Fileok\\p.txt","wt")))
{
fprintf(stderr,"Nem sikerült megnyitni az állományt");
return
-1;
}
for (i=0;i<10;i++)
fprintf(fp,"%4d",i);
fflush(fp);
fclose(fp);
if
(!(fp=fopen("A:\\Fileok\\p.txt","rt")))
{
fprintf(stderr,"Nem sikerült megnyitni az állományt");
return
-1;
}
i=0;
while (!feof(fp))
{
fscanf(fp,"%d",&i);
printf("%d",i);
}
fclose(fp);
while ((c=getch()) !=13);
}
A példában egész értékeket írunk ki egy szöveges állományba,
majd visszaolvassuk azokat. A visszaolvasásánál a file vége jelölésére az
feof(fp) függvényt
használjuk. Ez a file végére érve vesz föl
NULL értéket.
A másik példa egy állomány nevét kéri be, majd karakterenként
kilistázza a képernyőre.
#include <stdio.h>
#include <conio.h>
main()
{
char nev[25];
FILE *fp;
char c;
clrscr();
printf("Állomány
neve: ");
scanf("%24s",
nev);
clrscr();
fp = fopen ( nev,
"rt");
if( fp == NULL )
printf("Nem lehet megnyitni a(z) %s állományt\n", nev);
else {
while( (c = fgetc(fp)) != EOF )
putchar (c);
fclose (fp);
}
}
1.1.3
Bináris állományok
A bináris állományokat byte-onként vagy blokkonként
kezelhetjük. A byte-onkénti kezeléshez jól használható az előző részben leírt
fgetc és
fputc függvénypáros. A blokkonkénti kezelést pedig
az
fread és az
fwrite függvényekkel végezhetjük el.
Használatukat a következő példában figyelhetjük meg.
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
main()
{
char c;
FILE *bf;
int
i[10]={1,2,3,4,5,6,7,8,9,10},counter,sv;
clrscr();
if
(!(bf=fopen("A:\\fileok\\adat.dat","w+b")))
{
printf("Sikertelen file nyitás");
return
-1;
}
fwrite(i,sizeof(int),10,bf);
rewind(bf);
counter=fread(&sv,sizeof(int),1,bf);
printf("%4d",sv);
fseek(bf,3*sizeof(int),SEEK_SET);
/* A 4. elemre áll */
counter=fread(&sv,sizeof(int),1,bf);
printf("%4d",sv);
fseek(bf,0*sizeof(int),SEEK_CUR);
/* A rákövetkezőre áll */
counter=fread(&sv,sizeof(int),1,bf);
printf("%4d",sv);
fclose(bf);
while ((c=getch()) !=13);
}
Nézzük először az
fwrite függvényt. A függvény első paramétere a kiírandó változó neve,
második paramétere az adott struktúrához tartalmazó blokkméret, harmadik
paraméter a kiírandó elemek darabszáma, negyedik pedig az állomány mutatója.
Az
fread függvény hasonlóképpen paraméterezhető. Eltérés abban van hogy
beolvasáskor nyilván a változó címét kell megadni a függvénynek, a másik három
paraméter ugyanaz. Természetesen mindkét függvénynek van visszatérési értéke is.
Mindkettőnél a sikeresen kiírt illetve beolvasott blokkok számát adja vissza. Ez
az érték használható a sikertelen beolvasás illetve kiírás figyelésére. Ha a
fenti programban a
counter változó értéke nem egyenlő eggyel, akkor az azt jelenti, hogy nem
sikerült beolvasni adatot az állományból. Ezeknek a változóknak a megadása nem
kötelező, mint a fenti programból is látszik az
fwrite függvényt enélkül hívtuk meg.
A progarmban van még egy újdonság, az állományban való
pozícionálás. Erre az
fseek függvényt használjuk. Paraméterezése: első paraméter a file mutató,
második a blokkméret és egy egész szám szorzata (ennyiedik elemre fogunk állni),
harmadik pedig azt mutatja meg, hogy mihez viszonytjuk a pozícionálást.
SEEK_CUR esetén a
pillanatnyi pozícióhoz,
SEEK_SET
esetén pedig a file elejéhez. Vigyázzunk azonban ennek az alakalmazásával, a
sorszámozás most is a nulladik elemtől kezdődik, ennek a
SEEK_SET esetén lehet jelentősége. A pillanatnyi
pozícióval pedig az a helyzet, hogy amikor egy adat beolvasása megtörtént, akkor
a file mutató rögtön eggyel tovább lép, tehát, ha a szomszédos elemre akarunk
lépni, akkor természetesen a
fseek-ben 0-t kell adnunk a második paraméter helyén[3].