PB161 – Programování v C++
● ● ● ●
Proudy pro standardní zařízení Souborové proudy Paměťové proudy Manipulátory
Výhody objektového řešení ●
Nástroje pro IO operace jsou v C++ součástí knihoven ●
● ● ● ● ●
Hierarchie objektových typů
Bezpečnost Snadnost použití Rozšiřitelnost Přetížené operátory (zejména << a >>) „Jednotné použití“
Vstupy, výstupy – std. zařízení ios_base istream
●
●
●
istream
ostream iostream
●
vstupní operace, např. >>
●
instance: cin
ostream ●
výstupní operace, např. <<
●
instance: cout, cerr, clog
instance cin, cout, … definovány v
Příklad přetíženého operátoru << class moje_neco { private: int a, b; //...ostatni slozky,... public: friend ostream & operator<<(ostream &o, const moje_neco & neco); }; ostream & operator<<(ostream &o, const moje_neco & neco) { o<
std.cc
Příklad přetíženého operátoru >> class moje_neco { private: int a, b; //...ostatni slozky,... public: friend istream & operator>>(istream &o, moje_neco & neco); }; istream & operator>>(istream &i, moje_neco & neco) { i>>neco.a>>neco.b; return i; }
Souborové proudy ●
Hlavičkový soubor
●
Třídy: ●
ifstream ●
●
ofstream ●
●
výstupní
fstream ●
●
vstupní
vstupně výstupní
Při otevírání proudu pomocí třídy fstream specifikujeme I/O/IO otevření proudu.
Souborové proudy ifstream vstup(„nazev“); ofstream vystup(„nazev“); fstream vv; vv.open(„nazev“, ios_base::in | … ); if(!vv) { chyba(); } vv.close(); vv.open(...);
Souborové proudy fstream::fstream(const char* jmeno, ios_base::openmode mode); ● Openmody: ●
●
●
●
in ●
otevře soubor pro čtení
●
otevře soubor pro zápis
●
otevře soubor na konci, lze se přesunout pomocí seekp()
●
otevře soubor na konci, nelze změnit
out ate app
Souborové proudy ●
trunc ●
●
binary ● ●
●
neexistujeli soubor, nastane chyba (staré implementace, nepoužívat)
noreplace ●
●
soubor bude otevřen jako binární (např. nelze <<, >>) neníli uvedeno, otevře se v textovém režimu
nocreate ●
●
existujeli soubor, smaže se
existujeli soubor, nastane chyba (staré implementace, nepoužívat)
Pozor na typ jména souboru (není string) ●
const char *
Souborové proudy – binární soubor istream& read( char* buffer, streamsize num ); ●
přečte num bytů z proudu a uloží do bufferu
ostream& write( const char* buffer, streamsize num ); ●
zapíše do proudu num bytů z bufferu
istream& get( char& ch ); načte znak a uloží do ch ostream& put( char ch ); ●
●
vloží do výstupního souboru znak z ch
Souborové proudy – binární soubor, posun ●
Vstupní proudy ●
pos_type tellg(); ●
●
ostream& seekg( off_type offset, ios::seekdir origin );
●
ostream& seekg( pos_type position ); ●
●
vrací současnou pozici v proudu
nastaví aktuální pozici v proudu
Výstupní proudy ●
pos_type tellp(); ●
vrací současnou pozici v proudu
●
ostream& seekp( off_type offset, ios::seekdir origin );
●
ostream& seekp( pos_type position ); ●
nastaví aktuální pozici v proudu
Souborové proudy – zjištění velikosti souboru ●
ios_base::seek_dir ●
●
●
beg ●
posun vůči začátku
●
posun vůči aktuální pozici
●
posun vůči konci
cur end
fin.seekg(0, ios_base::end); int velikost = fin.tellg();
Souborové proudy 1. úkol a) Napište program, který se bude chovat stejně jako standardní systémová funkce cp (copy v MSDOS). Použití: cpy zdroj cíl
Program musí fungovat i pro binární soubory.
b) Program nechť nepřepisuje existující soubory, ale zahlásí chybu. Nepoužívejte noreplace.
Vstupy, výstupy – manipulátory ●
●
Hlavičkový soubor Vkládají se „mezi“ operátory vstupu a výstupu (dojde k volání funkce). ● ●
●
Prototyp jednoduchého manipulátoru ●
●
cout<<"|"<<setw(10)<<"ahoj"<<"|"<<endl; vypíše „| ahoj|“ ostream& manipulator (ostream&);
Většina manipulátorů má platnost až do změny ● nastaví „stav“ proudu ● (neplatí pro setw)
Vstupy, výstupy – manipulátory (2) ●
boolalpha/noboolalpha ●
●
true, false / 1,0
left/right ●
zarovnání vlevo/zarovnání vpravo cout<
Ahoj 145 145
Vstupy, výstupy – manipulátory (3) ●
fixed ●
●
scientific ●
●
výstupy budou v osmičkové, šestnáctkové soustavě
setbase(n) ●
●
reálná čísla ve „vědeckém“ tvaru
oct, hex ●
●
reálná čísla s pevnou řádovou čárkou
určuje (0, 8, 10, 16) číselnou soustavu
endl ●
zapíše konec řádku ('\n')
Vstupy, výstupy – manipulátory (4) ●
setprecision(n) ●
●
setfill(int n) ● ●
●
výplňový znak např. u setw(), jeli vstup kratší
flush ●
●
přesnost
vyprázdní buffer
skipws/noskipws ●
přeskakuj/nepřeskakuj bílé znaky
Vstupy, výstupy – manipulátory (5) ●
skipws/noskipws
char c;
char c;
while (cin >> c) cout <
cin>>noskipws; while (cin >> c) cout <
ahoj jak se mas ahojjaksemas
ahoj jak se mas ahoj jak se mas
Vstupy, výstupy <string> istream& getline( istream& is, string& s,\ char delimiter = '\n' ); ●
● ●
Přečte celý řádek z proudu „is“ a uloží do parametru „s“. Pracuje s řetězci dle C++ Není nutné uvádět maximální délku řetězce. string s; getline(cin, s); cout << "napsano: " << s << endl;
Vstupy, výstupy istream& getline( char* buffer,\ streamsize num, char delim ); ● Přečte nejvýše „num 1“ znaků a uloží je do „buffer“ = řetězec dle C. ● Oddělovač není nutno specifikovat (přetíženo). char radek[100]; while(fin.getline(radek, 100)) cout << "precteno: " << radek << endl;
Paměťové proudy Hlavičkový soubor <sstream> ●
istringstream ●
●
ostringstream ●
●
vstupní paměťový proud výstupní paměťový proud
stringstream ●
vstupně výstupná paměťový proud
Vhodné pro konverze, buffery, formátování v paměti atd.
Paměťové proudy ●
Iniciace konstruktorem (např.) ●
●
ostringstream pproud(„blabla");
Metora str(); ●
vrátí obsah proudu ●
●
Nastaví obsah ●
●
string str(); void str( string s );
C++ analogie C ● ●
sprintf() scanf()
Stav proudu ●
Vyjadřuje příznak typu iostate
●
Definovány v ios_base ●
goodbit ●
●
eofbit ●
●
poslední operace se nezdařila
badbit ●
●
konec souboru
failbit ●
●
OK
pokus o neplatnou operaci
hardbit ●
HW chyba
Stav proudu ●
Metody pro přístup: ● ● ● ●
●
void ios::clear(iostate stav=goodbit); ●
●
bool ios::good() const; bool ios::eof() const; bool ios::fail() const; bool ios::bad() const; jeli proud v chybovém stavu, musíme pro další použití vymazat příznak
void ios::setstate(iostate stav); ●
nastavení daného příznaku
Úkol – stavy proudu ●
Napište program, který bude číst jen čísla typu int, ostatní bude ignorovat a vždy zahlásí, že vstup nebyl OK, ale bude pokračovat dále.