18. unora ´ 2015, Brno ´ Pˇripravil: David Prochazka
Vstupn´ı a vystupn´ ´ ı proudy v C++ Programovac´ı jazyk C++
Vstup dat do programu
ˇ Obsah pˇredna´ sky 1
Vstup dat do programu
2
´ Terminal
3
Textov´y soubor
4
´ ı soubor Binarn´
5
XML
Strana 2 / 26
Vstup dat do programu
Strana 3 / 26
´ Vstup parametru˚ z pˇr´ıkazove´ rˇadky Programu je obˇcas potˇreba pˇredat parametry (format c:). V C++ mus´ıme deklarovat parametry funkce main ´ nasleduj´ ıc´ım zpusobem: ˚ 1 2 3 4 5
int main ( int argc , char * argv []) { std :: cout << " pocet parametru : " << argc ; for ( int i =0; i < argc ; i ++) cout << argv [ i ] << " " ; std :: cout << std :: endl ; ...
´ +1. Promn argc vrac´ı poˇcet pametru, ˚ ktere´ byly pˇredany ˇ obsahuje parametr. Promn argv je pole, kde kaˇzda´ bunka K parametrum ˚ pˇristupujeme klasicky – argv[1], argv[2], ... ´ od 1! argv[0] je jmeno ´ Parametry jsou cˇ ´ıslovany prog.
´ Terminal
ˇ Obsah pˇredna´ sky 1
Vstup dat do programu
2
´ Terminal
3
Textov´y soubor
4
´ ı soubor Binarn´
5
XML
Strana 4 / 26
´ Terminal
Strana 5 / 26
´ a cten´ ˇ ´ Vystup ´ na terminal ı z terminalu Pouˇz´ıva´ se knihovna iostream. ´ Pro zapis lze pouˇz´ıt standardn´ı bufferovan´y v´ystup – cout, na nebufferovan´y chybov´y v´ystup – cerr, nebo na bufferovan´y chybov´y v´ystup – clog. Pro naˇcten´ı lze pouˇz´ıt standardn´ı vstup – cin. 1
# include < iostream >
2 3 4 5 6 7 8 9 10
int main ( void ){ int cislo ; std :: cout << " Napis cislo " << std :: endl ; std :: cin >> cislo ; std :: cout << " Napsal jsi : " << cislo << std :: endl ; std :: cerr << " Nastala neznama chyba " << std :: endl ; return 0; }
´ Terminal
ˇ ´ ı proudu˚ na urovni Pˇresmerov an´ ´ OS ˇ pˇresmeruj v´ypis pˇr´ıkazu do souboru – ls>jmenoSouboru.txt ˇ pˇresmeruj standardn´ı v´ystup – program 1>jmenoSouboru.txt ˇ pˇresmeruj chybov´y v´ystup – program 2>jmenoSouboru.txt zahod’ chybov´y v´ystup – program 2>\dev\null ˇ pˇresmeruj chybov´y v´ystup na standardn´ı – 2>&1
Strana 6 / 26
´ Terminal
Strana 7 / 26
´ ´ ´ s proudem Manipulatory – nastroje pro praci Pro manip. s parametrem je potˇreba pouˇz´ıt knihovnu iomanip. ´ ´ endl – konec ˇradku a vyprazdni buffer. ´ setw(x) – poˇcet znaku˚ na ktere´ bude zarovnano. ˇ ano. ´ setfill(’x’) – jak´ym znakem bude vyplnov ´ sˇ estnactkov ´ ´ dec, hex, oct – v´ypis cˇ ´ısel v destkove, e, ˇ osmiˇckove´ soustave. 1 2 3 4 5 6 7 8
# include < iostream > # include < iomanip > int main ( void ) { int c = 1000 , b = 9; std :: cout << " b = " << setw (3) << b << std :: endl << " c = " << c << std :: endl ; std :: cout << setw (3) << setfill ( ’. ’) << hex << c ; ...
´ Terminal
Strana 8 / 26
ˇ ıtan´ ´ ı formatovan ´ ´ Metody nac´ eho vstupu ´ na cˇ ´ısla, slova, vety. ˇ Vstup je automaticky konvertovan ´ ´ getline cˇ te cele´ ˇradky, ne jen do prvn´ıho b´ıleho znaku. ´ a´ na bufferu enter, coˇz muˇ ´ >> nechav z e b´ y t probl em pˇri ˚ ´ ı s getline. kombinovan´ 1 2 3
std :: cout << " Veta : " ; std :: string veta ; getline ( std :: cin , veta );
4 5 6 7
std :: cout << " Slovo : " ; std :: string slovo ; std :: cin >> slovo ;
8 9 10 11
std :: cout << " Cislo : " ; int cislo ; std :: cin >> cislo ;
´ Terminal
Strana 9 / 26
ˇ ıtan´ ´ ı do (pole) znaku˚ Metody nac´ Se vstupem pracujeme jako se znaky, resp. polem znaku. ˚ Znaky lze i vracet do streamu. get necha´ ukoˇcovac´ı symbol v bufferu, getline jej vybere. 1 2 3 4 5
char line [ maxSize ]; std :: cout << " Veta : " << std :: endl ; // nacte radek , posledni parametr volitelny std :: cin . getline ( line , maxSize , ’\ n ’ ); std :: cout << line ;
6 7 8 9 10 11
std :: cin . get ( someChar ); // precte znak char line [ maxSize ]; std :: cout << " Veta : " ; std :: cin . get ( line , maxSize ); // nacte pocet znaku std :: cout << line ;
´ Terminal
Strana 10 / 26
ˇ en´ ˇ ı bufferu Vycist Obˇcas je potˇreba zruˇsit nezpracovane´ znaky z bufferu. ignore zruˇs´ı zvolen´y poˇcet znaku˚ aˇz po ukonˇcovac´ı symbol. Pˇr´ıklad ukazuje pouˇzit´ı max. velikosti streamu. 1 2 3 4 5
# include < limits > ... std :: cin . ignore ( std :: numeric_limits < std :: streamsize >:: max () , ’\ n ’ );
Textovy´ soubor
ˇ Obsah pˇredna´ sky 1
Vstup dat do programu
2
´ Terminal
3
Textov´y soubor
4
´ ı soubor Binarn´
5
XML
Strana 11 / 26
Textovy´ soubor
Strana 12 / 26
´ Prace se souborem ´ ´ Pracujeme take´ s proudy, metody cˇ ten´ı/zapisu jsou stejne. Mus´ıme naˇc´ıst knihovnu (tˇr´ıdu) fstream. V´ystupn´ı proud pak deklarujeme jako ofstream, vstupn´ı ifstream. 1 2 3 4 5
# include < iostream > # include < fstream > int main (){ std :: ofstream out ; out . open ( " temp . txt " );
6
for ( int i =1; i <=10; i ++) { out << i << endl ; } out . close (); // nezapominat , vse je v bufferu
7 8 9 10 11
}
Textovy´ soubor
Strana 13 / 26
´ Kontrola zapisu do souboru Vˇzdy je vhodne´ kontrolovat, zda se povedlo soubor otevˇr´ıt (vytvoˇrit). 1 2 3 4 5 6 7 8 9 10 11 12
# include < iostream > # include < fstream > int main (){ std :: ofstream out ; out . open ( " pokus . txt " ); if ( out . is_open ()) { out << " radka textu " ; out . close (); } else { std :: cout << " Soubor se nepodarilo nacist ... " ; } }
Textovy´ soubor
Strana 14 / 26
ˇ Cten´ ı ze souboru ˇ mus´ıme naˇc´ıst knihovnu fstream. Opet Vstupn´ı proud pak deklarujeme jako ifstream. 1 2 3 4 5 6 7 8 9 10 11 12
# include < iostream > # include < fstream > int main (){ std :: string slovo ; std :: ifstream in ; in . open ( " temp . txt " ); if ( in . is_open ()) { while ( in >> slovo ) std :: cout << slovo << " " ; std :: cout << std :: endl ; in . close (); } }
Textovy´ soubor
Strana 15 / 26
´ ˇ e´ Nazev souboru v promenn ˇ a´ obsahuj´ıc´ı nazev ´ Pokud je promenn souboru pole znaku, ˚ ´ je vˇse v poˇradku. Pokud se jedna´ o instanci tˇr´ıdy string, je nutne´ pouˇz´ıt metodu c str(). Od C++11 funguje i klasick´y string. 1 2 3 4 5 6 7 8 9 10
# include < iostream > # include < fstream > int main (){ std :: string jmenoSouboru = " ahoj . txt " ; std :: ifstream in ; in . open ( jmenoSouboru . c_str ()); if ( in . is_open ()) { ... } }
Textovy´ soubor
´ ı kopie souboru po znac´ıch Trivialn´ 1 2 3
int main () { std :: ifstream from ( " soubor1 . txt " ); std :: ofstream to ( " soubor2 . txt " );
4
char ch ; while ( from . get ( ch )) to . put ( ch );
5 6 7 8
from . close (); to . close ();
9 10 11
}
Strana 16 / 26
Textovy´ soubor
Strana 17 / 26
´ Reˇzimy prace se souborem ´ Slouˇz´ı k nastaven´ı reˇzimu cˇ ten´ı nebo zapisu. Pˇr´ıklad syntaxe: 1 2
std :: ofstream out ; out . open ( " pokus . txt " , ios_base :: app |...);
in – otevˇre soubor pro cˇ ten´ı (v´ychoz´ı pro cˇ ten´ı, nen´ı nutne´ ´ psat). ´ ´ out – otevˇre soubor pro zapis (v´ychoz´ı pro zapis, nen´ı ´ nutne´ psat). ate – po otevˇren´ı hledej konec souboru. app – pˇridej text na konec souboru. ´ trunc – zkrat’ existuj´ıc´ı soubor na nulovou delku. ´ ı reˇzim. binary – binarn´
Textovy´ soubor
Strana 18 / 26
Skoky v souboru seekg(position) – skok na pozici ve v´ystupn´ım proudu. seekp(position) – skok na pozici ve vstupn´ım proudu. seekg(skok, pozice) – skok o zadan´y poˇcet bytu˚ (v´yst.). seekp(skok, pozice) – skok o zadan´y poˇcet bytu˚ (vst.). Identifiktory pozice: ´ beg – zaˇcatek souboru. end – konec souboru. ´ ı pozice. cur – aktualn´ 1 2 3 4
// prepis 2. bod v souboru s daty in . seekg ( sizeof ( Point3D ) , ios_base :: beg ); // bude se cist 3. bod v poradi in . seekp (2* sizeof ( Point3D ) , ios_base :: beg );
Textovy´ soubor
Strana 19 / 26
ˇ a´ prace ´ Obosmern se souborem 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
// priklad vymeni stare cislo za nove podle ID // 164 585 -555 -3490 while ( ioData . good ()) { int id ; string number ; // nacte nove id a provede kontrolu ioData >> id ; if ( id == searchedID ) { // skok na soucasnou pozici cteni ioData . seekp ( ioData . tellg ()); // tellg vrati pozici // zapsani nove hodnoty ioData << " " << inNewNumber ; break ; // chtelo by udelat lepe } ioData >> number ;
´ ı soubor Binarn´
ˇ Obsah pˇredna´ sky 1
Vstup dat do programu
2
´ Terminal
3
Textov´y soubor
4
´ ı soubor Binarn´
5
XML
Strana 20 / 26
´ ı soubor Binarn´
Strana 21 / 26
´ ı soubory Binarn´ ´ e“ ˇ cˇ ´ıst, zapisuj´ı data ve formatu ´ jako Nedaj´ı se normaln ” ˇ jsou v pameti. ´ s pˇrenosem techto ˇ Problem souboru˚ mezi platformami. ´ Pˇr´ınosem je vyˇssˇ ´ı rychlost prace.
´ ı soubor Binarn´
Strana 22 / 26
´ ´ ıho souboru Zapis do binarn´ ´ ´ ıho souboru lze pouˇz´ıt nap. funkci Pro zapis do binarn´ write. Kop´ıruje urˇcit´y poˇcet bajtu˚ (znaku) ˚ od pozice, na kterou ukazuje ukazatel. 1
int pole [4]={1 ,2 ,3 ,4};
2 3 4
std :: ofstream out ; out . open ( " vystup . dat " , ios_base :: binary );
5 6 7 8 9 10
if ( out . is_open ()) { out . write (( char *) pole , sizeof ( pole )); // pretyp . out . close (); } else std :: cout << " Nepodarilo se otevrit ! " << std :: endl ;
´ ı soubor Binarn´
Strana 23 / 26
ˇ ´ ıho souboru cten´ ı z binarn´ Pouˇz´ıva´ se funkce read: 1
1
read ( const char * buf , streamsize poet );
char pole [4];
2 3 4
std :: ifstream in ; in . open ( " vstup . dat " , ios_base :: binary );
5 6 7 8 9 10
if ( in . is_open ()) { in . read (( char *) pole , sizeof ( pole )); // pretypovani in . close (); } else std :: cout << " Nepodarilo se otevrit ! " << std :: endl ;
XML
Strana 24 / 26
ˇ Obsah pˇredna´ sky 1
Vstup dat do programu
2
´ Terminal
3
Textov´y soubor
4
´ ı soubor Binarn´
5
XML
XML
Strana 25 / 26
ˇ ı se) XML soubory (nezkous´ ´ ı dat. XML je jednoznaˇcn´y trend v oblasti pˇrenosu a ukladn´ ´ ´ Proˇc je XML tak zaj´ımave/pouˇ z´ıvane? 1 2 3 4 5 6 7 8 9 10 11 12
xml version = " 1.0 " encoding = " ISO -8859 -1 " ? > < notes > < note > < to > Tove to > < from > Jani from > < heading > Reminder heading > < body > Don ’t forget me this weekend ! body > note > < note > ... note > notes >
XML
Strana 26 / 26
XML soubory ´ ı XML (SAX, SAX2, Existuje ˇrada metod pro zpracovan´ DOM, XMLWriter, ...). ˇ s´ımi z techto ˇ Nejvznamnejˇ metod jsou verze SAX a DOM parseru. ˚ ˇ ı automaticke´ Pro C/C++ existuj´ı knihovny, ktere´ umoˇznuj´ ´ ı XML: Qt, libxml2, Xerxes, expat, Arabica, aj. zpracovan´ (http://www.ibm.com/developerworks/xml/library/ x-ctlbx.html) ´ s XML v C++ za men ´ eˇ komfortn´ı Osobneˇ povaˇzuji praci neˇz ve skriptovac´ıch jazyc´ıch (pˇr´ısna´ typovost C++).