C++ I/O rendszere A C++ támogatja a C I/O rendszerét is Objektum-orientált I/O rutinok C++ I/O rendszerének előnye: új típus integrálása könnyen kialakítható
Automatikusan nyitott stream-ek cin standard input Keyboard cout standard output Screen cerr standard error Screen clog bufferelt verziója a cerr-nek Screen Átirányíthatók!
Osztályok az I/O műveletek támogatására iostream.h fájlban: streambuf Legalacsonyabb szintű osztály: alap input output műveletek ios Magasabb szintű: formattálás, hibaellenőrzés, státusz információ istream, ostream, iostream
Témakörök Formattált I/O I/O manipulátorok Inserter-ek Extractor-ok Fájl kezelés
Formattált I/O A C-hez hasonlóan C++-ban is lehetséges az adatok megjelenítése különböző formátumban Minden stream-hez tartoznak ún. formátum flag-ek (long típusú egész érték) Névvel rendelkező konstansok az ios osztályon belül ezeknek a flagek-nek a beállítására
Ios osztályban definiált format flag-ek class ios { public: static const flags skipws left right internal
dec , okt , hex ,
showbase , showpoint , uppercase, showpos ,
fixed , scientific , unitbuf ,
adjustfield, basefield, floatfield
long flags(); long flags(long f); long setf (long flags); A flags által specifikált flag-ek beállításra kerülnek long unsetf (long flags); A flags által specifikált flag-ek törlésre kerülnek
Flag-ek jelentése skipw whitespace karakterek (space, tab és újsor) elhagyása a bemeneten left, mezőigazítás: feltöltés az érték után right feltöltés az érték előtt internal feltöltés az előjel és az érték között
dec //a számrendszer alapja egészeknél :10 (decimális) hex //16 (hexadecimális okt // 8 (oktális)
Flag-ek jelentése showbase kiíráskor oktálisak elé 0, hexadecimálisaok elé 0x előtag showpoint a záró nullák megjelenítése showpos + jel megjelenítése pozítiv érték előtt uppercase e és x helyett E és X.
scientific. lebegőpontos numerikus. érték megjelenítése scientific scientific lebegőpontos numerikus érték megjelenítése scientific jelöléssel (d.ddddddEdd) fixed lebegőpontos érték megjelenítése fixpontos formátumba (dddd.dd)
adjustfield, //mezőigazításal kapcsolatos jelző basefield, //egész számrendszer alapszámával kapcsolatos jelző floatfield //lebegőpontos kimenettel kapcsolatos jelző
A format flag-ek állítása setf() függvény segítségével (ios osztály tagja) long setf (long flags) A flags által specifikált flag-ek beállításra kerülnek Visszaadott érték: az előző format flags
Példa a showpos flag beállítására stream.setf(ios::showpos) vagy cout.setf (ios::showbase | ios:: hex);
Flag-ek törlése long unsetf (long flags); unsetf() függvény segítségével (ios osztály tagja long unsetf (long flags); A flags által specifikált flag-ek törlésre kerülnek Visszaadott érték: az előző format flags
Flag-ek lekérdezése flags() függvény segítségével (ios osztály tagja long flags() Visszaadott érték: az előző format flags
Flag-ek beállítása bitmintával flags() függvény segítségével (ios osztály tagja long flags(long f) A függvény a bitmintának megfelelően állítja a flag-eket f: bitminta Visszaadott érték: az előző format flags
További formátum paraméterek Mezőszélesség pontosság kitöltő karakterek
Minimális mezőszélesség int width(int w); Az outputra kerülő adat minimálisan w számú helyet foglal el. Ha az adat hosszabb, akkor hosszabb mezőszélességben kerül kiírásara A mezőszélesség visszaáll az alapértelmezés szerintire
Pontosság int precision (int p) P: a lebegőpontos érték outputja esetén a tizedespont után megjelenítendő tizedesjegyek száma Visszaadott érték: az előző pontosság Alapértelmezés: 6 tizedes jegy
Mező kitöltése char fill ( char ch) ch: az új töltő karakter Visszaadott érték: a régi töltő karakter Amennyiben a mezőszélesség nagyobb, mint a kiírásra kerülő érték jegyeinek száma, akkor ezzel a kitöltő karakterrel kerül feltöltésre a mező többi része
Példa #include <iostream.h> main() { cout << 123.23 << " hello " << 100 << '\n‘; cout << 10 << ' ' << -10<< '\n'; cout << 100.0 << '\n';
Példa cout.setf(ios::hex| ios::scientific); cout << 123.23 << " hello " << 100 << '\n'; cout.setf(ios::showpos); cout << 10 << ' ' << -10<< '\n'; cout.setf(ios::showpoint| ios::fixed); cout << 100.0; return 0; }
Eredmény 123.23 hello 100 10 –10 100 1.2323e+02 hello 64 A fffffff6 +100.000000
I/O manipulátorok Speciális függvények a formátum információk megadására Néha könnyebb használni őket, mint az ios formátum flag-eket és függvényeket. include <iomanip.h> szükséges a használatukhoz, ha a manipulátonak van paramétere
Manipulátorok dec endl ends flush hex oct resetiosflags(long f) setbase( int base) setfill ( int ch) setiosflags(long f) setprecision(int p) setw( int w) ws
Inserter-ek létrehozása A C++-ban az output: insertion << operátor neve: insertion operator << átdefiniálása: inserter function, vagy röviden inserter
Inserter formája { // az inserter törzse return stream; } ostream &operator<<(ostream &stream, class-name ob) { // az inserter törzse return stream; }
Fontos! Az első paraméter hivatkozás egy ostream típusú objektumra (ostream az ios osztályban van definiálva) A második paraméter az az objektum, ami outputra kerül A visszaadott érték egy hivatkozás a stream-re, amely ostream típusú
Az inserter-ek tulajdonságai Nem tagfüggvényei annak az osztálynak, amelyre definiálták. (miért?) Megsérti az egységbezárás elvét? friend függvényként kell generálni
Extractor-ok definiálása A C++-ban az input: extractor << operátor neve: extraction operator << átdefiniálása: extractor function, vagy röviden extractor
Extractor formája { // az extractor törzse return stream; } istream &operator<<(istream &stream, class-name ob) { // az extractor törzse return stream; }
Fájl I/O alapok A következő fájlokra van szükség: fstream.h ifstream.h ofstream.h
Stream létrehozása ifstream in; //input ofstream out; //output fstream io; //input és output
Fájl megnyitása void open (char *fájl-név, int mode, int access)
mode értékek: ios::app (nyitás outputra hozzáfűzéssel) ios::ate ios::in (nyitás inputra) ios::nocreate (hiba, ha a fájl még nem létezik) ios::noreplace (hiba, ha a fájl már létezik) ios::out (nyitás outputra) ios::trunc (ha volt ilyen nevű fájl, akkor törölve lesz és újat hoz létre)
access értékek 0 normál fájl 1 csak olvasható fájl 2 rejtett fájl 4 rendszer fájl 8 archív fájl
Példa fájl megnyitására ofstream out; out.open(„teszt”, ios::out, 0); fstream mystream; mystream.open(„teszt”, ios::in | ios::out);
Fájl megnyitásának sikeressége if (!mystream) { cout << „Fájl nyitás nem sikerült!”; } A stream értéke 0, ha sikertelen a fájl nyitás.
Fálj megnyitása konstruktorral ifstream mystream.open(„teszt”);
Fájl zárása mystream.close();
Fálj végének vizsgálata int eof(); Nem zérus értéket ad vissza, ha vége a fájlnak, egyébként pedig zérus értéket.
Bináris I/O műveletek istream &get(char &ch); ostream &put(char ch); istream &read(unsigned char *buf, int num); ostream &write(const unsigned char *buf, int num); int gcount(); istream &get(char *buf, int num, char delm=‘\n’); int get(); istream &getline(char *buf, int num, char delim=‘\n’); int peek(); istream &putback(char c); ostream &flush();
Random elérés istream &seekg(streamoff offset, seek_dir origin); ostream &seekp(streamoff offset, seek_dir origin); Streamoff: iostream.h-ban definiált típus seek_dir egy enumerációs érték: ios::beg ios::cur ios::end
Fájl pointerek get pointer: a következő input művelet helye put pointer: a következő output művelet helye A megfelelő seek() fv. A kurrens get illetve put pointert offset bájttal mozgatja a specifikált kezdethez képest.
Fájl pointerek pozíciójának lekérdezése streampos tellg(); streampos tellp();
I/O státusz goodbit 0 nincs hiba 1 hiba van eofbit 0 fájl vége 1 egyébként failbit 0 nem végzetes hiba badbit 0 végzetes hiba 1 egyébkénthiba van
Hibakezelő függvények int bad(); int eof(); int fail(); int good();
Hiba törlése void clear(int flags=0);
#include <iostream.h> #include <fstream.h> main() { ofstream fout("teszt"); if(!fout){ cout << "nem tudja megnyitni a fájlt!"; return 1; } fout<<"Hello!\n"; fout<<100<<' ' << hex <<100<< endl; fout.close();
ifstream fin("teszt"); if(!fin) { cout << "nem tudja megnyitni a fájlt!"; return 1; } char str[80]; int i,j; fin>> str>>i>>j; cout<<str<<endl<<i<<' '<<j<<endl; fin.close(); return 0;
#include <iostream.h> #include <fstream.h> #include <stdio.h> main(int argc, char *argv[]) { if (argc!=2) { cout << "nem j¢ param‚terek!\n"; return 1; } ofstream out ( argv[1] ); if(!out){ cout << "nem tudja megnyitni a f jlt!\n"; return 1; }
char str[80]; cout<<„írj sztringet diszkre, majd return-nel állj le!\n"; do { cout<<": "; gets(str); out<<str<<endl; } while (*str); out.close(); return 0; }
#include <iostream.h> #include <fstream.h> main(int argc, char *argv[]) { if (argc!=3) { cout << "nem j¢ param‚terek!\n"; return 1; } ifstream fin(argv[1]); ofstream fout(argv[2]); if(!fout){ cout << "nem tudja megnyitni az output f jlt!\n"; return 1; }
if(!fin){ cout << "nem tudja megnyitni az input fájlt!\n"; return 1; } char ch; fin.unsetf(ios::skipws); while (!fin.eof()) { fin>>ch; if (ch==' ') ch='|'; fout<<ch; } return 0;
#include <iostream.h> #include <fstream.h> main(int argc, char *argv[]) { if (argc!=3) { cout << "nem j¢ param‚terek!\n"; return 1; } ifstream fin(argv[1]); ofstream fout(argv[2]); if(!fout){ cout << "nem tudja megnyitni az output f jlt!\n"; return 1; }
if(!fin){ cout << "nem tudja megnyitni az input f jlt!\n"; return 1; } char ch; fin.unsetf(ios::skipws); while (!fin.eof()) { fin>>ch; if (ch==' ') ch='|'; fout<<ch; } return 0;