A C++ nyelvben a függvény nevek túlterhelésével biztonságosabbá tehetnénk az adatok kiírását és beolvasását.

Hasonló dokumentumok
Bevezetés Kiíratás Beolvasás Formázás Fájlkezelés Gyakorló feladatok C++ I/O. Bevezetés. Izsó Tamás február 20. Izsó Tamás C++ I/O / 1

Programozás II. 2. Dr. Iványi Péter

Pénzügyi algoritmusok

C++ programozási nyelv Struktúrák a C++ nyelvben Gyakorlat

Fejlett programozási nyelvek C++ Sablonok és adatfolyamok

1. Gyakorlat. Rövid elméleti összefoglaló. <tárolási osztály>típus <típus > változónév <= kezdőérték><, >;

7. gyakorlat. Fájlkezelés IO haladó Függvények haladó

Programozás I gyakorlat

Programozás C++ -ban 2007/1

1. Alapok. Programozás II

1. Írjunk programot mely beolvas két egész számot és kinyomtatja az összegüket.

Programozás alapjai gyakorlat. 2. gyakorlat C alapok

A C programozási nyelv I. Bevezetés

A C programozási nyelv I. Bevezetés

Programozás C és C++ -ban

Informatika terméktervezőknek

Alkalmazott modul: Programozás 2. előadás. Procedurális programozás: adatfolyamok, adatsorok kezelése

7. gyakorlat Sorozatok, Fájlkezelés

Bevezetés a programozásba I.

Programozás I gyakorlat. 10. Stringek, mutatók

Programozás. (GKxB_INTM021) Dr. Hatwágner F. Miklós május 6. Széchenyi István Egyetem, Gy r

Programozás alapjai gyakorlat. 4. gyakorlat Konstansok, tömbök, stringek

Bevezetés a programozásba I.

HORVÁTH ZSÓFIA 1. Beadandó feladat (HOZSAAI.ELTE) ápr 7. 8-as csoport

Bevezetés a programozásba II. 5. Előadás: Másoló konstruktor, túlterhelés, operátorok

Programozás I gyakorlat

117. AA Megoldó Alfréd AA 117.

Programozás 6. Dr. Iványi Péter

Maximum kiválasztás tömbben

Programozás C és C++ -ban

Programozás II. 2. gyakorlat Áttérés C-ről C++-ra

Mutatók és címek (ism.) Programozás alapjai C nyelv 8. gyakorlat. Indirekció (ism) Néhány dolog érthetőbb (ism.) Változók a memóriában

Programozási nyelvek I. 5. előadás (Gregorics Tibor anyagának felhasználásával)

Kivételkezelés a C++ nyelvben Bevezetés

Objektumorientált programozás Pál László. Sapientia EMTE, Csíkszereda, 2014/2015

Bevezetés a programozásba I 10. gyakorlat. C++: alprogramok deklarációja és paraméterátadása

Miről lesz ma szó? A PROGAMOZÁS ALAPJAI 1. Dinamikus változók. Dinamikus változók. Dinamikus változók. Dinamikus változók. 7.

Felhasználó által definiált adattípus

STL gyakorlat C++ Izsó Tamás május 9. Izsó Tamás STL gyakorlat/ 1

Algoritmizálás + kódolás C++ nyelven és Pascalban

Programozás alapjai C nyelv 8. gyakorlat. Mutatók és címek (ism.) Indirekció (ism)

7. Laboratóriumi gyakorlat: Vezérlési szerkezetek II.

Programozás alapjai C nyelv 5. gyakorlat. Írjunk ki fordítva! Írjunk ki fordítva! (3)

S z á m í t ó g é p e s a l a p i s m e r e t e k

A C programozási nyelv VI. Parancssori argumentumok File kezelés

1. Feladat: beolvas két számot úgy, hogy a-ba kerüljön a nagyobb

1. Template (sablon) 1.1. Függvénysablon Függvénysablon példányosítás Osztálysablon

C++ programozási nyelv Konstruktorok-destruktorok

Programozás alapjai C nyelv 4. gyakorlat. Mit tudunk már? Feltételes operátor (?:) Típus fogalma char, int, float, double

Írjon olyan programot a standard könyvtár alkalmazásával, amely konzolról megadott valós adatokból meghatározza és kiírja a minimális értékűt!

Java II. I A Java programozási nyelv alapelemei

1. Egyszerű (primitív) típusok. 2. Referencia típusok

Programozás alapjai 2.Gy: A C nyelv alapjai P R O

Programozás Minta programterv a 1. házi feladathoz 1.

A függvény kód szekvenciáját kapcsos zárójelek közt definiáljuk, a { } -ek közti részt a Bash héj kód blokknak (code block) nevezi.

8. Gyakorlat. Rövid elméleti összefoglaló: Fájlkezelés

Szkriptnyelvek. 1. UNIX shell

Programozás 1. Dr. Iványi Péter

Mit tudunk már? Programozás alapjai C nyelv 4. gyakorlat. Legnagyobb elem keresése. Feltételes operátor (?:) Legnagyobb elem keresése (3)

Bevezetés a programozásba. 11. Előadás: Esettanulmány

Elemi alkalmazások fejlesztése I. Olvassunk be egy fájlból egész számokat egy tömbbe. Keressük meg a tömb valamely

500. AA Megoldó Alfréd AA 500.

Programozás alapjai. (GKxB_INTM023) Dr. Hatwágner F. Miklós szeptember 27. Széchenyi István Egyetem, Gy r

Mintavételes szabályozás mikrovezérlő segítségével

Programozás C nyelven (3. ELŐADÁS) Sapientia EMTE

Programozási nyelvek Java

INFORMATIKA tétel 2019

Bevezetés a programozásba Előadás: Objektumszintű és osztályszintű elemek, hibakezelés

Kifejezések. Kozsik Tamás. December 11, 2016

Szövegek C++ -ban, a string osztály

5. gyakorlat. Konstansok Tömbök Stringek

Kifejezések. Kozsik Tamás. December 11, 2016

Bevezetés a programozásba I 8. gyakorlat. C++: szövegfolyamok, intelligens tömbök

1.1. A forrásprogramok felépítése Nevek és kulcsszavak Alapvető típusok. C programozás 3

Bevezetés a programozásba. 8. Előadás: Függvények 2.

ISA szimulátor objektum-orientált modell (C++)

Globális operátor overloading

Bevezetés a C++ programozásba

INFORMATIKA tétel 2018

Stack Vezérlés szerkezet Adat 2.

INFORMATIKA javítókulcs 2016

Operációs rendszerek. 11. gyakorlat. AWK - szintaxis, vezérlési szerkezetek UNIVERSITAS SCIENTIARUM SZEGEDIENSIS UNIVERSITY OF SZEGED

Bevezetés a programozásba I.

Programozási nyelvek Java

Programozási nyelvek JAVA EA+GY 1. gyakolat

Programozás alapjai II. (1. ea) C++

Programozás alapjai II. (1. ea) C++

C programozás. 6 óra Függvények, függvényszerű makrók, globális és

Bevezetés a programozásba I 8. gyakorlat. C++: szövegfolyamok, intelligens tömbök. Adatfolyamok Hibalehetőségek

Bánsághi Anna 2014 Bánsághi Anna 1 of 35

Alkalmazott modul: Programozás 2. előadás. Procedurális programozás: adatfolyamok, adatsorok kezelése. Adatfolyamok kezelése. Adatfolyamok kezelése

/* Az iter függvény meghívása és a visszatérő érték átadása a gyok változóba */ gyok = iter( n, a, e ) ;

2018, Funkcionális programozás

Algoritmizálás + kódolás C++ nyelven és Pascalban

ELTE SAP Excellence Center Oktatóanyag 1

Mérnöki programozás 7. Szerkesztette: dr. Vass Péter Tamás

BASH script programozás II. Vezérlési szerkezetek

Sztringkezelő függvények. A string típusú változók kezelése, használata és szerepük a feldolgozás során

Java II. I A Java programozási nyelv alapelemei

Függvény pointer. Feladat: Egy tömbben soroljunk fel függvényeket, és hívjuk meg valahányszor.

Átírás:

1. Motiváció C nyelvben a printf és a scanf függvények használata a programozótól nagy körültekintést igényel. A változó számú argumentum miatt a fordító nem tudja ellenőrizni, hogy a formátum mezőben megadott, kiírandó adatok száma és típusa megegyezik-e a paraméterlistával. i n t i =19, double p i = 3. 1 4 ; p r i n t f ( "%d\n", i ) ; / / OK p r i n t f ( "%d %d\n", i, 19, p i ) ; / / h i b á s formátum mező, vagy paraméter A C++ nyelvben a függvény nevek túlterhelésével biztonságosabbá tehetnénk az adatok kiírását és beolvasását. void w r i t e ( c o n s t i n t i ) p r i n t f ( "%d", i ) ; void w r i t e ( c o n s t double r ) p r i n t f ( "%f", r ) ; void w r i t e ( c o n s t char * s ) p r i n t f ( "%s", s ) ;..... i n t i =4, double p i = 3. 1 4 ; w r i t e ( "4*Pi=" ) ; w r i t e ( 4* p i ) ; w r i t e ( "\n" ) ; Ez a megoldás kényelmetlen. A C++ nyelvben a «és a» operátorok túlterhelésével oldották meg a feladatot. Az előző kiíratás megoldása: c o u t << "4*pi=" << 4* p i << \n ; A túlterhelt operátorokat a C++ fordító függvényhívásokra fordítja. Az egyes függvények ostream& értékkel térnek vissza, ami lehetőséget ad, a függvények láncolására. Az előzővel ekvivalens programrészlet: operator < <( ( operator < <( cout, "4*pi=" ) ). operator < < ( 4 * 3. 1 4 ), \n ) ; «Inserter (beszúrás) a kiírandó folyamba beszúrja a megjelenítendő adatokat.» Extractor (kinyerés) a bejövő adatfolyamból kinyeri a soron következő adatot. Előre definiált streamek. cin standard input cout standard output cerr standard error clog buffer-olt változata a standard errornak. 1

2. Kiírás 2.1. Felhasználó által definiált inserter s t r u c t P a i r i n t x ; i n t y ; ; o s t r e a m& operator < <( o s t r e a m& o, c o n s t P a i r& p ) return o << ( << p. x <<, << p. y << ) ; P a i r p1 = 2, 5 ; c o u t << p1 << e n d l ; 2.2. Azonnali output megjelenítése A hatékonyság érdekében az» inserter a karaktereket bufferbe teszi, és csak nagyobb egységekben jeleníti meg. Interaktív programok esetén, szükséges lehet kevesebb adat azonnali megjelenítése is, ezt a flush speciális adat (manipulátor) kiírásával érjük el. c o u t << "Kérem az x értékét \n" << f l u s h ; A sorvége endl érték nem csak a NL karaktert teszi az outputra, hanem azonnali megjelenítést kér. Az előző példával ekvivalens programrész: c o u t << "Kérem az x értékét " << e n d l ; 2.3. Bináris kiíratás i n t c= A ; c o u t. p u t ( c ) ; / / egy k a r a k t e r t í r k i c o u t << ( char ) c ; / / egy k a r a k t e r t í r k i c o u t. w r i t e ( ( char *)&c, s i z e o f ( c ) ) ; / / e g é s z b i n á r i s k i í r a t á s a 2.3.1. Tetszőleges adatok konvertálása karakterfüzérré Akik használták a sprintf függvényt, azoknak jó hír, hogy C++-ban az ostrstream segítségével ugyanezt tehetik, biztonságosabban és egyszerűbben. # i n c l u d e < s s t r e a m > # i n c l u d e < i o s t r e a m > using namespace s t d ; i n t main ( ) o s t r i n g s t r e a m os ; os << 123 << << 456 << ends ; c o u t << os. s t r ( ) << e n d l ; return 0 ; 3. Beolvasás i n t i ; double r ; c i n >> i >> r ; 2

3.1. Adatfolyam állapot lekezelése A következő függvények az adatfolyam állapotát adják vissza: bool good() bool eof() bool fail() bool bad() A beolvasás sikeres volt. Fájl vége volt. Az utolsó beolvasás sikertelen volt, de adatvesztés nem lépett fel. Javíthatatlan hiba. Ilyenkor a fail() függvény is jelez. Ezeket a függvényeket ritkán hívjuk meg, mert a szabványos input, output könyvtár tervezésénél a következő operátorok túlterhelésével olyan trükkel éltek, ami leegyszerűsíti a hibakezelést. operator void*() bool operator!() A cast operator nem NULL pointert (C++-ban nem 0-át) ad vissza, ha!fail(). Meghívja a fail() függvény, és annak a visszatérési értékét adja vissza. i n t i ; i f ( c i n >> i ).... / / rendben v o l t a b e o l v a s á s e l s e.... / / h i b á s i n p u t A cin» i kifejezés megegyezik a cin.operator»( i ) függvény hívással, ami istream& értékkel tér vissza. Ezzel a típussal a fordító az if(...) utasítás feltételrészében nem tud mit kezdeni, ezért automatikusan meghívja az operator void*() típuskonvertáló operátort, és ez a fail() függvény alapján 0 vagy nem 0 címmel tér vissza, ami megfeleltethető egy logikai értéknek. 3.2. Beolvasó ciklus szervezése c o n s t i n t MAXPAIR=10; P a i r vp [MAXPAIR ] ; i n t x, y ; i n t n p a i r =0; while ( n p a i r < MAXPAIR && cin >>x && c i n >>y ) vp [ n p a i r ]. x=x ; vp [ n p a i r + + ]. y=y ; 3.3. Felhasználó által definiált extractor i s t r e a m& operator > >( i s t r e a m& i, P a i r& p a i r ) i >> p a i r. x >> p a i r. y ; return i ; 3.4. Saját hibaállapot állítás Az előző kódrészletben az olvasás például akkor volt sikertelen, ha egész szám helyett nem számjegy karakter jött. Legyen az a feladat, hogy akkor is hibát jelzünk, ha negatív egész számokat olvasunk. 3

i s t r e a m& operator > >( i s t r e a m& i, P a i r& p a i r ) i >> p a i r. x >> p a i r. y ; i f (! i ) return i ; / / hiba v o l t i f ( p a i r. x <0 p a i r. y<0 ) i. c l e a r ( i o s : : b a d b i t i. r d s t a t e ( ) ) ; return i ; A clear() függvény neve sajnos félrevezető, mert nem törli, hanem beállítja a hiba flag-et. Az rdstate() függvény visszaadja az aktuális hibaállapotot, és ezzel bitenkénti vagy kapcsolattal egybe állítjuk a badbit flag-et. 3.5. Maximálisan megengedett karakterszám beállítása String char* beolvasása esetén vigyázni kell, nehogy több adatot olvassunk, mint amennyi memória rendelkezésre áll. Veszélyes kód (buffer overflow): char p [ 5 ] ; c i n >> p ; A width(int) függvény segítségével megadhatjuk a maximálisan beolvasható karakterek számát, a stringet lezáró nullát is beleszámítva. char p [ 5 ] ; c i n. width ( s i z e o f ( p ) ) ; c i n >> p ; Ugyanezt kényelmesebben megtehetjük a setw(int) manipulátorral. char p [ 5 ] ; c i n >> setw ( s i z e o f ( p ) >> p ; Egy sor beolvasásához használhatjuk a getline függvényt. A függvény harmadik paramétere a sor végét jelző karakter értéke, alapértéke természetesen a NL karakter. char l i n e [ 1 0 0 ] ; c i n. g e t l i n e ( l i n e, s i z e o f ( l i n e ) ) ; 3.6. Szóközök beolvasása Ha a karakterek olvasásánál mi szeretnénk a whitespace-eket feldolgozni, akkor használjuk a get(char) függvényt, vagy a noskipws manipulátort. A get(char) függvény mindig beolvassa a szóközöket is. 4

char c ; c i n >> noskipws ; while ( c i n >> c ) cout <<c ; c i n >> noskipws ; c i n. g e t ( c ) ;.... while ( c i n. g e t ( c ) )..... 3.7. Bináris input Tetszőleges bináris adat olvasásánál a read() függvényt használjuk. i n t v [ 1 0 0 ] ;.... c i n. r e a d ( ( char *) v, s i z e o f ( v ) ) ; 3.7.1. Karakterfüzér konvertálása tetszőleges adatra Akik használták az sscanf függvényt, azoknak jó hír, hogy C++-ban az istrstream segítségével ugyanezt tehetik, biztonságosabban és egyszerűbben. # i n c l u d e < s s t r e a m > i n t iv1, i v 2 ; i s t r i n g s t r e a m i s ( "123 456" ) ; i s >> i v 1 >> i v 2 ; / / k o n v e r t á l á s 4. Formázás 4.1. Mezőszélesség A mezőszélesség beállítás csak az utána következő egy adatra érvényes. Kiírásnál csak akkor hatásos, ha a megadott érték nagyobb, mint a kiírandó karakterek száma. c o u t. width ( 5 ) ; c o u t << 12 << << 34 << << 56 << e n d l ; Egyszerűbben manipulátorral: c o u t << setw ( 5 ) << 12 << << 34 << << 56 << e n d l ; A mezőszélesség beállítás érvényes a beolvasásnál is, erre már adtunk meg példát. 5

4.2. Kitöltés és jobbra, balra igazítás Ha a mezőszélesség megadásánál nagyobb helyet adunk meg, mind amekkora a kiírandó szöveg hossza, akkor megadhatjuk, hogy a szöveg a mező jobb vagy bal széléhez legyen igazítva, és az üres helyekre milyen kitöltő karakter kerüljön. c o u t. f i l l ( * ) ; c o u t << l e f t << setw ( 5 ) << 13 << "," ; c o u t << setw ( 5 ) << 25 << "," ; c o u t. f i l l ( # ) ; c o u t << r i g h t << setw ( 5 ) << 14 << "," << e n d l ; output: 13***,25***,###14, 4.3. Számrendszer megadása A kiírásnál és beolvasásnál választhatunk decimális, oktális és hexadecimális számrendszerek közül. A showbase flag beállításával a számrendszer alapja is kiolvasható a szám alapján. i n t x =64; c o u t << dec << x << << hex << x << << o c t << x << << e n d l ; c o u t << showbase << dec << x << << hex << x << << o c t << x << << e n d l ; output : 64 40 100 64 0x40 0100 Olvasásnál: c i n >> dec >> x >> hex >> y >> o c t >> z 6

4.4. Manipulatorok név jelentés boolalpha bool típus szövegesen (true, false) dec tízes számrendszer endl newline és flush ends null karakter fixed tizedes tört alak flush stream buffer kiürítés hex hexadecimális számrendszer left balra igazítás noboolalpha bool formátuma szám (0,1) noshowbase ne mutassa a számrendszer alakját noshowpoint ne írjon tizedesvesszőt (pontot) noshowpos ne írjon pozitív előjelet noskipws ne olvassa át a whitespace karaktereket nouppercase számoknál (E) és hexa értékeknél (A-F) ne írjon nagybetűt oct nyolcas számrendszer resetiosflags formátum flagek törlése right jobbra igazít scientific exponenciális alak setfill kitöltő karakter beállítás setiosflags beállítja a megadott jelzőbiteket setprecision kiírandó tizedesjegyek beállítása setw mezőszélesség showbase mutassa a számrendszer alakját showpoint írjon tizedesvesszőt (pontot) showpos írjon pozitív előjelet is skipws whitespacek átolvasása uppercase számoknál (E) és hexa értékeknél (A-F) nagybetűt használjon 4.5. Fájlkezelés / / u s i n g f s t r e a m c o n s t r u c t o r s. # i n c l u d e < i o s t r e a m > # i n c l u d e < f s t r e a m > using namespace s t d ; i n t main ( ) f s t r e a m os ( "test.txt", f s t r e a m : : i n f s t r e a m : : o u t ) ; os << "PI:" << 3. 1 4 << e n d l ;..... os. c l o s e ( ) ; return 0 ; 7

Megnyitási módok: flag megnyitási mód app (append) minden egyes kiírás előtt a fájl végére pozícionál ate (at end) megnyitás után a fájl végére pozícionál binary (binary) bináris mód in (input) olvasás engedélyezése out (output) írás engedélyezése trunc (truncate) megnyitáskor a fájl tartalmának a törlése Fájl megnyitás open() függvény segítségével: / / f s t r e a m : : open # i n c l u d e < f s t r e a m > using namespace s t d ; i n t main ( ) f s t r e a m f i o ; f i o. open ( "test.txt", f s t r e a m : : i n f s t r e a m : : o u t f s t r e a m : : app ) ; / / >> i / o o p e r a t i o n s here << f i o. c l o s e ( ) ; return 0 ; 8