next up previous contents
Elõre: A main függvény Fel: Bevitel és kivitel Vissza: Alacsony szintû I/O

Folyam jellegû I/O

A folyam jellegû állománykezelésnél az alapvetõ mûvelet egy karakter beolvasása és kiírása. A folyamok azonosítása file-mutatókkal történik,  amelyek szerepe hasonló az alacsony   szintû   kezelésnél   használt   file-leírókéhoz. A FILE egy, a rendszer által az stdio.h include file-ban definiált struktúra, és a file-mutató egy ilyen struktúrát megcímzõ pointer. A file-mutatók között szintén vannak elõredefiniáltak, ezek az stdin, stdout, stderr, és ugyanaz a jelentésük, mint a 0-ás, 1-es és 2-es file-leíróknak. (A 3-as és 4-es leíróknak az stdaux és stdprn elõre definiált file-mutatók felelnek meg.) Egyéb file-mutatók a FILE* fopen(const char* name, const char* mode) deklarációjú könyvtári függvény hívásával nyerhetõk egy adott állomány megnyitása kapcsán. (A name sztring a megnyitandó állomány neve, mode pedig az állomány kezelési módját - írás, olvasás, hozzáfûzés - határozza meg.) A file-megnyitási hibákat a visszaadott NULL érték jelenti. Egy karakter beolvasását a getc() makró végzi:

            c = getc(fp);
Itt fp egy korábbi fopen hívás által visszaadott értéket tartalmazó, FILE *fp; definíciójú változó. A getchar() makró a getc(stdin) makróhívásnak egy rövidített formája. Ha a visszaadott érték az stdio.h-ban definiált EOF szimbólum, akkor az adott file végére értünk. A kivitel a putc(c, fp) makróval történik, ahol c a kiirandó karakter. A putchar(c) hasonlóan a putc(c, stdout) rövidítésére szolgál. Ezekben makrókban a paraméter csak egyszer kerül kiértékelésre, így nem kell tartanunk kellemetlen mellékhatásoktól, ha bonyolultabb kifejezéseket használunk aktuális paraméterként. E makrók használatára vonatkozó példákat a pelda.c programban találhatunk.

Formátumozott outputot a int printf(const char* format, ...), illetve az int fprintf(FILE* outfile, const char* format, ...) deklarációjú függvényekkel állíthatunk elõ. Az elõbbi a standard outputra (stdio), míg az utóbbi az outfile file-pointer által meghatározott, írható file-ba nyomtat. A nyomtatási képet a format sztring határozza meg. A függvények visszatérési értékül a formátum specifikáció szerint kinyomtatandó paraméterek számát adják.

A format sztring kétféle karaktert tartalmazhat. Egyrészt normál karaktareket, amelyek minden további nélkül a kimeneti állományba másolódnak, másrészt konverzió specifikációkat. A konverzió specifikációk hatására a format sztringet követõ további argumentumok kerülnek rendre kinyomtatásra az egymást követõ specifikációk alapján. Minden specifikáció egy százalékjel (%) karakterrel kezdõdik, és egy vezérlõ karakterrel zárul. A % és a vezérlõ karakter között még az alábbi karakterek állhatnak (a felsorolás szerinti sorrendben):

Mint említettük, a mezõszélesség vagy a pontosság helyett megadhatjuk a * karaktert is. Ebben az esetben a megfelelõ értéket az eddig feldolgozott argumentumokat követõ elsõ argumentum - ami egy int típusú kifejezés kell legyen - fogja meghatározni. Például a
            printf("%.*s",max,str);
utasítás hatására az str sztringbõl a max változóban lévõ érték által meghatározott számú karakter kerül a standard kimenetre.

A formátum sztringben használható vezérlõ karaktereket a 1.6. táblázatban foglatuk össze.

Figyelem! A printf függvény az elsõ paramétere alapján határozza meg, hogy még hány, és milyen típusú további paramétere van. Mindenféle "szemét" kerülhet az outputra, ha a formátum sztringet nem a specifikációnak megfelelõ számú, vagy típusú paraméter követi. A printf-rõl elmondottak természetesen a printf-függvénycsalád többi tagjára (fprintf, sprintf) is vonatkoznak. (Az sprintf függvény ugyanazt végzi, mint az fprintf, de file helyett egy karaktertömbbe "nyomtat").
 


Karakter Argumentum típus Nyomtatási kép

d,i int elõjeles decimális egész
o int elõjel nélküli oktális egész
x,X int hexadecimális egész a vezetõ 0x vagy 0X elõtag nélkül
u int elõjel nélküli decimális egész
c int unsigned char-rá való konvertálás után a megfelelõ karakter
s char* sztring karaktereit nyomtatja EOS-ig vagy az adott mezõszélesség határáig
f double [-]m.dddddd, ahol a d-k száma az elõírt pontosságtól függ. A pontosság alapértelmezésben 6, a 0 pontossággal a tizedes pont nyomtatása elnyomható
e,E double [-]m.dddddd e± xx vagy 
[-]m.dddddd E± xx, ahol a d-k száma az elõírt pontosságtól függ
g,G double ugyanaz, mint %e vagy %E, ha az exponens kisebb, mint -4 vagy nagyobb-egyenlõ, mint a pontosság, egyébként ugyanaz, mint %f. Nincsenek vezetõ 0-k vagy szóközök.
p void* pointer-érték; implementáció függõ, a BORLAND C++-ban tármodelltõl is függ
% nincs konverzió, maga a % karakter nyomtatódik

  1.6 táblázat: A printf függvénycsalád formátum-specifikáló sztringjeinek vezérlõ karakterei

Az  int  scanf(const char * format,  ...)  deklarációjú függvény a printf függvénynek megfelelõ beolvasó rutin. Ez a függvény az stdin állományról olvas be adatokat, és az esetek többségében a printf konverziók fordítottját hajtja végre.

A scanf karaktereket olvas a standard inputról, a format formátumspecifikáló sztring szerint értelmezi és konvertálja azokat, és a további argumentumai - amelyek a formátum specifikációnak megfelelõ típusú tárolási egységekre mutató pointerek - által meghatározott memória helyekre írja be a beolvasott értékeket.

A scanf befejezi az olvasást, ha a specifikációnak megfelelõ számú adatot már beolvasott, vagy ha az input valamilyen oknál fogva nem felel meg formátum-specifikációnak. Visszatérési értékül a sikeresen beolvasott adatok számát adja meg a scanf. Ez jól használható arra, hogy ellenõrizzük, tényleg annyi adatot olvasott-e be a programunk, mint ahányat kellett. Ha file vége után olvasnánk a scanf-fel, akkor visszatérési értékül az EOF-ot (end of file) kapjuk. Az EOF szimbólum az stdio.h include file-ban van definiálva. Ha visszatérési értékül 0-t kapunk, ez azt jelzi, hogy a soron következõ beolvasandó karakter nem felel meg a formátum-specifikációnak.

A format sztring az alábbi karaktereket tartalmazhatja:

  
Karakter Input adat Argumentum típus

d decimális egész int*
i egész szám akár oktális (vezetõ 0), akár hexadecimális (vezetõ 0x vagy 0X) formában int*
o oktális egész a vezetõ 0 elõtag nélkül int*
u elõjel nélküli decimális egész unsigned int*
x hexadecimális egész akár a 0x vagy 0X elõtaggal, akár anélkül int*
c karakter(ek). A soron következõ karakter (alapértelmezésben csak 1) kerül a megfelelõ memóriaterületre. A whitespace karakterek is beolvasásra kerülnek, következõ nem whitespace karakter olvasásához a %1s specifikációt használjuk. char*
s sztring beolvasása. A specifikációhoz tartozó pointer egy olyan tömbre kel mutasson, amely elegendõen nagy a beolvasandó karakterek és a sztring végét jelzõ EOS tárolására. char*
f,e,g E három vezérlõ karakter szolgál lebegõpontos számok beolvasására. Az elõjel, a tizedes pont és az exponens opcionális. Ha a specifikációban az l vagy az L elõtag is szerepel (például %lf), akkor az argumentum típusa: float*





double*
p a printf által produkált formátumú pointer értéket olvassa be void**
% nincs hatása

 1.7 táblázat: A scanf függvénycsalád formátum-specifikáló sztringjeinek vezérlõ karakterei

A d, i, o és x konverziót vezérlõ karakterek elõtt állhat a h elõtag, amely azt jelzi, hogy int* helyett short* típusú pointer áll az argumentum-lista megfelelõ helyén, illetve az l, vagy L elõtaggal azt jelezhetjük, hogy int* helyett long-ra mutatató pointer található az argumentum-listában. Ez utóbbi esethez hasonlóan az e, f és g vezérlõ karakterek elõtt álló l, vagy L elõtag arra utal, hogy float helyett double adattal van dolgunk. A BORLAND C++-ban az L elõtag a long double típusú adatok specifikálására szolgál.

Ahogy a formátumozott outputtal kapcsolatban függvénycsaládról beszéltünk, ugyanígy létezik a beolvasásra is a scanf függvénycsalád. Ha stdin helyett egy valamilyen más állományra vonatkozó adatfolyamból szeretnénk olvasni, akkor az fscanf függvényt használjuk. Sztringbõl való "olvasásra" az sscanf függvény szolgál.

Mind a printf, mind a scanf függvénycsalád esetében a n vezérlõ karakter hatására a már konvertált karakterek száma a specifikációhoz tartozó int* típusú az argumentum által megcímzett memóriahelyre kerül; nem történik semmiféle konverzió, és a konvertált adatok számlálója sem inkrementálódik.


next up previous contents
Elõre: A main függvény Fel: Bevitel és kivitel Vissza: Alacsony szintû I/O