C++ I/O
Bevezetés
Izsó Tamás
2014. február 20.
Section 1 Bevezetés
Izsó Tamás C++ I/O / 2
Irodalom
Paraméter illesztés függvénynév túlterhelés esetén
1 Pontos típus illeszkedés. Nincs szükség konverzióra.
2 Egész kiterjesztés : bool −> int, char −> int, short −> int, unsigned −> int, float −> double
3 Szabványos konverziók: double <−> int, T∗ −> void∗, Derived∗ −> Base∗, int −> unsigned int
4 Felhasználó által írt konverziók.
5 Változó függvény argumentum : ...
Mit ír ki C-ben és mit C++-ban?
char ch ;
p r i n t f ( "%d %d %d " , s i z e o f ( char ) , s i z e o f ( ch ) , s i z e o f ( ’ x ’ ) ) ;
Izsó Tamás C++ I/O / 4
Motiváció
# include < s t d i o . h>
void f o o ( ) {
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 ˝o ,
/ / vagy paraméter
}
Függvénynév túlterhelés
FILE ∗ w r i t e ( FILE ∗ f , const i n t i ) {
f p r i n t f ( f , "%d " , i ) ; r e t u r n f ;
}
FILE ∗ w r i t e ( FILE ∗ f , const double r )
{
f p r i n t f ( f , "%f " , r ) ; r e t u r n f ;
}
FILE ∗ w r i t e ( FILE ∗ f , const char ∗ s )
{
f p r i n t f ( f , "%s " , s ) ; r e t u r n f ;
}
Izsó Tamás C++ I/O / 6
Függvénynév túlterhelés
void f o o ( ) {
i n t i = 4 ;
double p i = 3 . 1 4 ;
w r i t e ( s t d o u t , " 4∗ P i = " ) ;
w r i t e ( s t d o u t , 4∗ p i ) ;
w r i t e ( s t d o u t , " \ n " ) ;
}
Függvények láncolása
void f o o ( ) {
i n t i = 4 ;
double p i = 3 . 1 4 ;
w r i t e ( w r i t e ( w r i t e ( s t d o u t , " 4∗ P i = " ) , 4∗ p i ) " \ n " ) ; }
Izsó Tamás C++ I/O / 8
Függvények láncolása infix operátor átdefiniálással
FILE∗ o p e r a t o r < <( FILE ∗ f , const i n t i ) {
f p r i n t f ( f , "%d " , i ) ; r e t u r n f ;
}
FILE∗ o p e r a t o r < <( FILE ∗ f , const double r ) {
f p r i n t f ( f , "%f " , r ) ; r e t u r n f ;
}
FILE∗ o p e r a t o r < <( FILE ∗ f , const char ∗s ) {
f p r i n t f ( f , "%s " , s ) ;
r e t u r n f ;
Operátorok láncolása
void f o o ( ) {
i n t i = 4 ;
double p i = 3 . 1 4 ;
o p e r a t o r < <( o p e r a t o r < <( o p e r a t o r < <( s t d o u t , " 4∗ P i = " ) , 4∗ p i ) ,
" \ n " ) ; }
Operátoros jelöléssel:
void f o o ( ) {
i n t i = 4 ; double p i = 3 . 1 4 ;
s t d o u t << " 4∗ P i = " << 4∗ p i << " \ n " ; }
Izsó Tamás C++ I/O / 10
<< és >> operátorok jelentése iostream esetén
<< Inserter (beszúrás) a kiírandó folyamba beszúrja a megjelenítend ˝o adatokat.
>> Extractor (kinyerés) a bejöv ˝o adatfolyamból kinyeri a
soron következ ˝o adatot.
El ˝ore definiált stream-ek.
cin standard input ( C megfelel ˝oje stdin ) cout standard output ( C megfelel ˝oje stdout ) cerr standard error ( C megfelel ˝oje stderr ) clog buffer-olt változata a standard errornak.
Izsó Tamás C++ I/O / 12
Stream modell
61 6c 6d 61 00 7b 00 00 00
18 2d 44 54 fb 21 09 40
ostream buffer
alma 123 3.14159265 memória
buffer istream
Section 2 Kiíratás
Izsó Tamás C++ I/O / 14
Felhasználó által definiált inserter
s t r u c t Komplex { double r ; double i ; } ;
ostream& o p e r a t o r < <( ostream& o , const Komplex& p ) { o << p . r << s t d : : showpos
<< p . i << s t d : : noshowpos << ’ i ’ ; r e t u r n o ;
}
void f o o ( ) {
Komplex p1 = { 2 , 5 } ;
c o u t << p1 << e n d l ; / / 2+5 i
}
Azonnali output megjelenítése
c o u t << " Kérem az x é r t é k é t \ n " << f l u s h ; Ezzel ekvivalens:
c o u t << " Kérem az x é r t é k é t " << e n d l ;
Izsó Tamás C++ I/O / 16
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 / / egész b i n á r i s k i í r a t á s a
c o u t . w r i t e ( ( char ∗)& c , s i z e o f ( c ) ) ;
Tetsz ˝oleges adatok konvertálása karakterfüzérré
# i n c l u d e <sstream >
# i n c l u d e < i o s t r e a m >
u s i n g 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 ;
r e t u r n 0 ; }
Izsó Tamás C++ I/O / 18
Keep it simple:
as simple as possible, but no simpler."
Albert Einstein
Section 3 Beolvasás
Izsó Tamás C++ I/O / 20
Adatfolyam állapot lekezelése
i n t i ;
i f ( c i n >> i ) { . . . . } / / rendben v o l t a beolvasás else { . . . . } / / h i b á s i n p u t vagy f i l e vége
bool good() A beolvasás sikeres volt.
bool eof () Fájl vége volt.
bool fail () Az utolsó beolvasás sikertelen volt, de adatvesztés nem lépett fel.
bool bad() Javíthatatlan hiba. Ilyenkor a fail ()
függvény is jelez.
Beolvasó ciklus szervezése
const 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 && c i n >>x && c i n >>y ) {
vp [ n p a i r ] . x=x ; vp [ n p a i r + + ] . y=y ; }
Izsó Tamás C++ I/O / 22
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 ; r e t u r n i ;
}
Saját hibaállapot állítás
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 ) r e t u r n i ; / / h i b a 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 ( ) ) ; }
r e t u r n i ; }
Izsó Tamás C++ I/O / 24
El ˝oírt érték beolvasása
# include < i o s t r e a m >
using namespace s t d ; i n t main ( )
{
c o u t << " Kerek 1− t o l 10− i g egy egesz szamot : \ n " ; i n t n = 0 ;
while ( c i n >>n ) { / / read
i f (1 <=n && n <=10) break ; / / check range c o u t << " Bocs , de " << n
<< " nem [ 1 : 1 0 ] k o z o t t van ; p r o b a l d meg u j r a \ n " ; }
c o u t << " B e o l v a s o t t e r t e k : " << n << e n d l ; r e t u r n 0 ;
}
Bolondbiztos beolvasás
# include< i o s t r e a m >
using namespace s t d ; i n t main ( )
{
c o u t << " Kerek 1−t o l 10−i g egy egesz szamot : \ n " ; i n t n = 0 ;
while ( n==0) { c i n >>n ; i f( c i n ) {
i f(1 <=n && n <=10) break; / / check range
c o u t << " Bocs , de " << n << " nem [ 1 : 1 0 ] k o z o t t van ; p r o b a l d meg u j r a \ n " ; n = 0 ;
} else i f( c i n . f a i l ( ) ) { / / nem egész szám j ö t t c i n . c l e a r ( ) ; / / h i b a á l l a p o t t ö r l é s e
c o u t << " Bocs de ez nem szam v o l t ; p r o b a l d meg u j r a \ n " ; char ch ;
/ / nem számjegyek á t o l v a s á s a while ( c i n >>ch && ! i s d i g i t ( ch ) ) ; i f ( ! c i n ) { / / nem t a l á l t u n k számjegyet
c e r r << " f e l a d t a m " ; r e t u r n 5 ; }
c i n . unget ( ) ; / / számjegy v i s s z a t é t e l e } else { / / e o f vagy r o s s z i n p u t
c e r r << " f e l a d t a m " ; r e t u r n 5 ; } ;
}
c o u t << " B e o l v a s o t t e r t e k : " << n << e n d l ; r e t u r n 0 ;
}
Izsó Tamás C++ I/O / 26
Mi rossz az el ˝oz ˝o programban?
Összekeveredtek a feladatok, úgymint érték olvasása
tevékenység kiírása hiba kiírás
rossz input átolvasása input tesztelése
Szét kell választani a különböz ˝o logikai részeket.
Bolondbiztos beolvasás újra
Logikailag különböz ˝o részek:
int get_int ( int low, int high );
int get_int ();
void skip_to_int ();
Izsó Tamás C++ I/O / 28
Hibás adatok átolvasása
void s k i p _ t o _ i n t ( ) {
i f ( c i n . f a i l ( ) ) { / / nem egész szám j ö t t c i n . c l e a r ( ) ; / / h i b a á l l a p o t t ö r l é s e char ch ;
/ / nem számjegyek á t o l v a s á s a while ( c i n >>ch ) {
i f ( i s d i g i t ( ch ) ) { c i n . unget ( ) ; r e t u r n ; }
} ; }
throw " f e l a d t a m ! " ; / / j o b b h í j á n s t r i n g
Egész érték beolvasás
i n t g e t _ i n t ( ) {
i n t n = 0 ; while ( t r u e ) {
i f ( c i n >>n ) r e t u r n n ;
c o u t << " Bocs de ez nem szam v o l t . " ; c o u t << " P r o b a l d meg u j r a \ n " ;
s k i p _ t o _ i n t ( ) ; }
r e t u r n 0 ; / / i d e nem j u t a v e z é r l é s }
Izsó Tamás C++ I/O / 30
Megadott intervallumba es ˝o érték beolvasása
i n t g e t _ i n t ( i n t low , i n t h i g h ) {
c o u t << " Kerek " << low "− t o l " << h i g h
<< "− i g egy egesz szamot : \ n " ; while ( t r u e ) {
i n t n = g e t _ i n t ( ) ;
i f ( low <=n && n<= h i g h ) r e t u r n n ;
c o u t << " Bocs de a szam nem e s e t t az i n t e r v a l l u m b a . " ; c o u t << " P r o b a l d meg u j r a \ n " ;
s k i p _ t o _ i n t ( ) ; }
r e t u r n 0 ; / / i d e nem j u t a v e z é r l é s }
Használat:
i n t n = g e t _ i n t ( 1 , 1 0 ) ;
c o u t << " n : " << n << e n d l ;
Section 4 Formázás
Izsó Tamás C++ I/O / 32
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.
void f o o ( ) {
char p [ 5 ] ;
c i n . w i d t h ( s i z e o f ( p ) ) ; c i n >> p ;
}
másként:
void f o o ( ) {
char p [ 5 ] ;
c i n >> setw ( s i z e o f ( p ) >> p ;
}
Sor olvasás
void f o o ( ) {
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 ) ) ; }
Izsó Tamás C++ I/O / 34
Szóközök beolvasása
void f o o ( ) {
char c ;
c i n >> noskipws ;
while ( c i n >> c && c ! = ’ \ n ’ ) cout <<c ; c i n >> skipws ;
/ / a g e t c ( ) minden k a r a k t e r t b e o l v a s c i n . g e t ( c ) ;
. . . .
while ( c i n . g e t ( c ) ) { . . . . . }
}
Bináris input
void f o o ( ) {
i n t v [ 1 0 0 ] ; . . . .
c i n . read ( ( char ∗ ) v , s i z e o f ( v ) ) ; }
Izsó Tamás C++ I/O / 36
Karakterfüzér konvertálása tetsz ˝oleges adatra
# i n c l u d e <sstream >
void f o o ( ) { i n t i v 1 , 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
}
Numerikus formátumok
Integer érték 1234 (decimal) 2322 (octal) 4d2 (hexadecimal) Lebeg ˝opontos szám
1234.57 (general)
1.2345678e+03 (scientific) 1234.567890 (fixed)
Lebeg ˝opontos szám pontossága 1234.57 (precision 6)
1234.6 (precision 5) Mez ˝oszélesség
|12| (alapértelmezés )
| 12| (12 4 karakter szélesen)
Izsó Tamás C++ I/O / 38
Mez ˝oszélesség
c o u t . w i d t h ( 5 ) ;
c o u t << 12 << ’ ’ << 34 << ’ ’ << 56 << e n d l ; egyszer ˝ubben:
c o u t << setw ( 5 ) << 12 << ’ ’ << 34 << ’ ’
<< 56 << e n d l ;
Kitöltés és jobbra, balra igazítás
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,
Izsó Tamás C++ I/O / 40
Számrendszer megadása
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
Lebeg ˝opontos szám pontossága
c o u t << 1234.56789 << ’ \ t ’ << f i x e d << 1234.56789 << ’ \ t ’
<< s c i e n t i f i c << 1234.56789 << ’ \ n ’ ; c o u t << g e n e r a l << s e t p r e c i s i o n ( 5 )
<< 1234.56789 << ’ \ t ’ << f i x e d << 1234.56789 << ’ \ t ’
<< s c i e n t i f i c << 1234.56789 << ’ \ n ’ ; c o u t << g e n e r a l << s e t p r e c i s i o n ( 8 )
<< 1234.56789 << ’ \ t ’ << f i x e d << 1234.56789 << ’ \ t ’
<< s c i e n t i f i c << 1234.56789 << ’ \ n ’ ;
output :
1234.57 1234.567890 1.234568e+03 1234.6 1234.56789 1.23457e+03
1234.5679 1234.56789000 1.23456789e+03
Izsó Tamás C++ I/O / 42
Manipulátorok összefoglalása 1
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 ˝ot (pontot) noshowpos ne írjon pozitív el ˝ojelet
noskipws ne olvassa át a whitespace karaktereket
nouppercase számoknál (E) és hexa értékeknél (A-F) ne írjon nagybet ˝ut
oct nyolcas számrendszer
Manipulátorok összefoglalása 2
név jelentés
resetiosflags formátum flagek törlése
right jobbra igazít
scientific exponenciális alak setfill kitölt ˝o karakter beállítás setiosflags beállítja a megadott jelz ˝obiteket setprecision kiírandó tizedesjegyek beállítása
setw mez ˝oszélesség
showbase mutassa a számrendszer alakját showpoint írjon tizedesvessz ˝ot (pontot) showpos írjon pozitív el ˝ojelet is
skipws whitespacek átolvasása
uppercase számoknál (E) és hexa értékeknél (A-F) nagybet ˝ut használjon
Izsó Tamás C++ I/O / 44
Section 5
Fájlkezelés
Fájlok megnyitása
# 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 ( " t e s t . t x t " , f s t r e a m : : i n | f s t r e a m : : o u t ) ; i f ( os )
{
os << " PI : " << 3.14 << e n d l ; . . . . .
os . c l o s e ( ) ; }
else c e r r < " Hiba a f á j l m eg n y it á sa k o r " << e n d l ; r e t u r n 0 ;
}
Izsó Tamás C++ I/O / 46
Megnyitási módok
flag megnyitási mód
app (append) minden egyes kiírás el ˝ott 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
Section 6 Gyakorló feladatok
Izsó Tamás C++ I/O / 48
Feladat 1.
Írja át az alábbi C programrészletet C++-ban szokásos iostream felhasználásával!
# include < s t d i o . h>
i n t main ( ) {
# d e f i n e LEN 20 char s t r [ LEN ] ;
i n t i = 1 0 ;
s c a n f ( "%19s " , s t r ) ; p r i n t f ( "%s \ n " , s t r ) ;
f p r i n t f ( s t d o u t , " H e l l o \ n " ) ; f p r i n t f ( s t d e r r , " H e l l o \ n " ) ; p r i n t f ( "%d \ n " , i ) ;
p r i n t f ( "%04d \ n " , i ) ;
p r i n t f ( "%+d \ n " , i ) ;
p r i n t f ( "%x \ n " , i ) ;
p r i n t f ( "%X \ n " , i ) ;
p r i n t f ( "%02X \ n " , i ) ;
Feladat 2. Mit ír ki a program?
# include
< i o s t r e a m >
# include
< f s t r e a m >
using namespace
s t d ;
i n tmain ( ) {
f s t r e a m f s ( " alma . t x t " , f s t r e a m : : o u t | f s t r e a m : : t r u n c ) ;
i n ti = 1 6 ;
f s . w i d t h ( 4 ) ; f s << hex << i ;
f s . w i d t h ( 8 ) ; f s << o c t << i << ’ \ n ’ ;
doublep i = 3 . 1 4 1 5 9 ;
f s . f i l l ( ’ . ’ ) ;
f s . w i d t h ( 2 0 ) ; f s . p r e c i s i o n ( 4 ) ; f s << p i << ’ \ n ’ ;
f s . c l o s e ( ) ;
f s . open ( " alma . t x t " , f s t r e a m : : i n ) ;
charb u f [ 1 0 0 ] ;
while
( f s . g e t l i n e ( buf ,
s i z e o f( b u f ) ) ) c o u t << b u f << e n d l ;
f s . c l o s e ( ) ; c i n . i g n o r e ( 1 ) ;
r e t u r n0 ; }
Izsó Tamás C++ I/O / 50