II. Diel C++ II. – cout a vstupno-výstupné techniky I.

Michal Kyžňanský  /  29. 09. 2006, 00:00

Vstup a výstup sú dva smery prúdenia dát, ktoré sú oknom komunikácie programov. Osvetlíme si kľúčové prvky konzolového vstupu a výstupu jazyka C++. Tento článok bude úvodom do veľkej kapitoly pojednávajúcej o postupoch pri vstupno/výstupných operáciách. Kapitola bude rozčlenená na všetky možnosti, od konzole, cez presmerovanie až po komplexnú tému súborového výstupu a vstupu. Venovať sa budeme objektu cout.

Vstup je akcia, a výstup je zvyčajne reakcia. Teda ide o príčinu a dôsledok. Vstup a výstup je jednou zo základných kapitol programovania. Predstavuje komunikáciu programu so svojimi časťami ako aj s externým prostredím. Vstup a výstup majú mnoho podôb. Môže isť len o komunikáciu v rámci programu, alebo výstupy a vstupy, ktoré pochádzajú z vonku – zo súborov. V tomto článku sa zameriame sa konzolový vstup a výstup, ktorým jazyk C nedisponuje. Každý kto používal prvky jazyka C si určite pamätá konzolové príkazy ako printf - výstup a scanf- vstup, ktoré uložené v hlavičkovom súbore stdio.h – standard input/output. Jazyk C++ implementuje však omnoho krajšie metódy vstupu a výstupu. Keďže chceme sa odpútať od záťaže starého jazyka C, budeme používať aj C++ verziu hlavičkového súboru stdio.h, teda cstdio.

C++ využíva na vstup a výstup triedy definované v hlavičkových súboroch iostream a fstream. Hlavičkový súbor iostream vkladá aj hlavičkové súbory istream a ostream. Objekty cin – vstup a cout - výstup, ktoré budeme používať sú objektmi tried istream – input stream a ostream – output stream. Celkovo v tejto kapitole budú veľmi často skloňované pojmy ako odvodená triedam, a dedenie vlastností a funkcií. Vstup a výstup sú v jazyku C++ chápané ako prúdy.

Tieto prúdy majú svoju vyrovnávaciu pamäť, ktorá je pripojovaná k týmto prúdom a stará sa o prenos dát medzi cieľom a programom. Vyrovnávaciu pamäť je možné pretransformovať na buffer, ktorý pracuje s blokmi dát o určitej veľkosti čo je nielen efektívne, ale aj rýchle. Vyrovnávacia pamäť slúži hlavne na vyrovnanie rýchlosti medzi spracovávaním dát a ich získavaním zo zdroja.

Prúdy je možné presmerovať, aby získavali/vysielali dáta tam, kam chceme my, nie je to dané fixne. Implicitne predstavuje vstup klávesnica a výstup obrazovka ale tento stav je meniteľný. Dôležité je ešte spomenúť triedu streambuf (o ktorej si v ďalších dieloch povieme viac), ktorá vytvára vyrovnávaciu pamäť a obsahuje metódy na jej zaplnenie a vyprázdňovanie.

Pre pochopenie fungovania vstupu a výstupu je nutné si ukázať hierarchiu tried, strom tried, ktorý ukazuje, ktorá trieda je nadradená a ktoré sú odvodené. Odvodené triedy môžu používať funkcie, ktoré sú definované v materskej triede. Preto sa stretneme s množstvom funkcií, ktoré môže využívať viac odvodených tried. Ale dosť teoretizovania. Prezrite si hierarchiu tried. Nižšie umiestnené triedy dedia vlastnosti po tých, ktoré sú vyššie. Napríklad trieda iostream dedí po oboch triedach – istream a ostream, resp. je od nich odvodená. Taktiež teda disponuje zdedenými funkciami po triedach ios a ios_base.



Každá trieda prispieva svojim dielom ku komplexnosti vstupno/výstupnej architektúry jazyka C++. Postupne v nasledujúcich dieloch budeme odhaľovať pôvod každej z nich a jej funkčnosť.

1. cout – začiatok

Ako nám diagram ukazuje, cin je objektom triedy istream a cout je objektom triedy ostream. Pri použití týchto dvoch objektov budeme využívať niečo, čo vyzerá ako operátor bitového posunu doľava/doprava - << a >>. Tento operátor však v kombinácii s objektmi cin/cout predstavuje tok dát, vizuálnu pomocou pre použitie týchto objektov. K použitiu výstupného objektu cout sa viaže operátor <<, teda cout <<. Logicky objekt cin pracuje s operátorom >>, teda cin >>. Ak chceme používať objekty cin a cout, musíme vložiť hlavičkový súbor iostream - #include <iostream>. Na jednoduchom príklade si ukážeme, výpis reťazca “programujeme” pomocou objektu cout a tiež starou metódou printf, aby ste si všimli rozdiely.

cout
cout << "programujeme";


printf
printf("programujeme");  


Ďalšia ukážka bude spočívať v tom, ako objektom cout vypisujeme premenné, teda ich obsah.

int a = 15;
cout << "Vonku je " << a << " stupnov";


Oddelenie premennej od priamo vkladaných reťazcov je možné vidieť priamo na tomto príklade. Používa sa na to znovu operátor bitového posunutia.

Viac o operátore <<

Celkovo výstup pomocou cout, ktorý je objektom triedy ostream spoločne s operátorom << je až neskutočne jednoduchý oproti metóde printf. Možno to z týchto príkladov nebolo zrejmé, ale predvediem vám nasledovnú demonštráciu z ktorej to bude skutočne jasné.

Ak by sme chceli pomocou starej metódy printf vypísať napríklad vetu “Vysledok je” a ďalej za ňou pokračovať vo vypisovaní premenných obsahujúcich výsledok museli by sme na to ísť takto:

c = a + b;
printf("vysledok je:%d",c);


Všimnite si určujúci špecifikátor %. Každý, kto v jazyku C využíval metódy vstupu a výstupu printf a scanf vie, že musí vždy “povedať“ prekladaču, o aký dátový typ sa bude jednať. A toto je hlavný rozdiel, ktorý je medzi cout << a pritnf (). Objekt cout spoločne s operátorom bitového posunú << rozoznáva všetky bežné dátové typy sám. Rozoznávanie funguje tak, že pri výpise je tvar porovnávaný s prototypom definovaným v hlavičkovom súbore. Všimnite si nasledujúce porovnanie.

printf
int a = 35;
char slovo[] = "ahoj";
char c = 'X';

printf("vypisujem cislo, retazec a znak : %d %s %c", a, slovo, c);


cout
int a = 35;
char slovo[] = "ahoj";
char c = 'X';

cout << a <<" "<< slovo<<" "<< c;


Záver znie, že objekt cout urobí za nás pracú v podobe informovania prekladača o dátovom type.

V budúcom pokračovaní sa pozrieme na manipulátory, ktoré nám umožňujú upravovať rôznymi spôsobmi výstup realizovaný objektom cout.

Súvisiace články: Prehľad všetkých dielov

Neprehliadnite: