PB161: Jazyk C++ - 9

Vstupy a výstupy

Objektové řešení ANSI C++

Hierarchie tříd:

Třídy určené pro samotné V/V:

Navíc varianty s prefixem w (vícebajtové "široké" znaky wchar_t - Unicode)

Vše je v prostoru jmen std

Hlavičkové soubory

Provádění V/V operací

Přetížené operátory >> a <<

vstupní_proud >> položka >> položka ...

výstupní_proud << položka << položka ...

Položky:

Tyto operátory jako svou hodnotu vracejí svůj levý operand, proto je lze řetězit. Na to je nutno pamatovat při jejich přetěžování pro vlastní třídy!

Pokud V/V operace proběhne neúspěšně, vrátí operátor hodnotu, která při použití na místě logického výrazu je ekvivalentní false. Toho lze použít k testování úspěšnosti operace.

Další operace jsou dostupné jako metody:

Vstup

POZOR! Funkce getline() je definována (přetížena) také v hlavičkovém souboru string s jinými parametry: (proud, kam, koncový_znak). Lze ji tedy volat: 
např. cin.getline(cstr); kde cstr je céčkovský řetězec (pole znaků)
nebo cin.getline(cstr,80)
nebo getline(cin, str);  kde str je string
nebo getline(cin, str, ':');

Výstup

Manipulátory

Celkem 30, nejdůležitější:

endl nový řádek + flush
ends znak \0 + flush
flush vyprázdni výstupní buffer
left zarovnávej doleva
right zarovnávej doprava
scientific exponentový tvar
fixed neexponentový tvar
dec v desítkové soustavě
oct v osmičkové soustavě
hex v šestnáctkové soustavě
ws přeskoč bílé znaky (na vstupu)
setprecision(int) počet míst
setw(int) šířka výstupního pole (jen pro následující položku!)
setfill(int) výplňkový znak

Manipulátory s parametry vyžadují hlavičkový soubor <iomanip>

Souborové proudy

Soubor se otevře konstruktorem třídy:

ifstream vstup("nazev_souboru");
if(!vstup) // ohlas chybu

nebo:

fstream vstup;
vstup.open("nazev_souboru",ios_base::in);
if(!vstup) // ohlas chybu

2. parametr může být in (vstup), out (výstup), app (připsat na konec), ate (otevřít na konci), trunc (smazat), binary nebo jejich kombinace (např. in|out|binary). Tyto konstanty jsou definovány ve třídě ios_base.

Soubor se zavře automaticky při vyvolání destruktoru; je možno také explicitně vyvolat metodu close().

Paměťové proudy

Neotevírají se. Řetězec se zadá jako parametr konstruktoru, např.

#include <iostream>
#include <sstream>
using namespace std;

string chyba(int kod)
{ ostringstream Zprava;
  Zprava << "Chyba cis. " << kod;
  return Zprava.str();
}
//Jina možnost:
  ostringstream Zprava("Chyba cis. ");
  Zprava << kod;

Přizpůsobování

Přetížení operátorů << a >>

Např. výstup komplexního čísla ve tvaru (real,imag)

ostream& operator<<(ostream& proud, komplex z)
{ return proud << '(' << z.real() << ',' << z.imag() << ')'; }

Analogické přetížení vstupního operátoru by bylo obtížnější (nutno ošetřit chyby).

POZOR: Vstupní položky musí být odkazy, aby operátor do nich mohl ukládat. Naproti tomu u výstupních položek je to nežádoucí, neboť by to znemožnilo do výstupního seznamu psát výraz objektového typu (například cout << komplex1-komplex2;). 

Řešením je 

a) buď jako pravý operand operátoru << použít přímo objektový typ (například vlastní typ komplex), což může být neefektivní, nebo 
b) konstantní odkaz (const komplex&)

Vlastní manipulátory

Jednoduchý příklad (manipulátor  oddel, který vloží do výstupu řádek tvořený kombinací -*-*-*-:

ostream& oddel(ostream& proud)
{ return proud << "\n-*-*-*-" << endl;   
}

Lze vytvářet i vlastní manipulátory s parametry, je to však složitější.

Další možnosti

Existuje ještě řada dalších metod a manipulátorů. Umožňují např. podrobně zjišťovat stav V/V systému a ovládat ho.

Starší objektové řešení

Je použito v některých starších překladačích.

Hlavní rozdíly:

Pozůstatek z C

Dá se používat i pod C++, ale není to vhodné - prostředky C++ jsou vhodnější a navíc dovolují transparentní rozšíření na soukromé datové typy.

Hlavičkový soubor <stdio.h>, resp. <cstdio>

Řízeno strukturou FILE

Otevření a zavření souboru

FILE *fp; // fp je tzv. proud
fp=fopen(název_souboru,režim); // při chybě vrátí NULL
fclose(
fp); // při chybě vrátí EOF

Automaticky jsou otevřeny "standardní soubory" - proudy stdin, stdout, stderr

Formátovaný V/V - rodina printf/scanf

printf(formát,výrazy); // vrací počet znaků
scanf(
formát,ukazatele); // vrací počet položek

fprintf(fp,formát,výrazy);
fscanf(
fp,formát,ukazatele);

sprintf(buffer,formát,výrazy);
sscanf(
buffer,formát,ukazatele);

Formátovací položky

Obecný tvar: %příznaky šířka.přesnost kód

Kód Typ Způsob výpisu Poznámka
d nebo i int dekadicky Pro long int se před typ přidá l, pro short int se přidá h
o oktalově
x hexadecimálně
f float nebo double běžný tvar Pro double se před typ přidá l, pro long double se přidá L
e mantisa e exponent
g podle hodnoty jako f nebo jako e
c char    
s char * (tj. textový řetězec) proměnný počet znaků podle délky řetězce  

Znakový V/V - rodina get/put

Příkaz: Význam:
ch = getc(fp); Přečte 1 znak ze souboru
ch = getchar(); Přečte 1 znak ze standardního vstupu (klávesnice)
ungetc(ch, fp); Vrátí znak ch do vstupního bufferu, takže následující vstupní funkce jej přečte znovu
putc(ch, fp); Zapíše 1 znak do souboru
putchar(ch); Zapíše 1 znak na standardní výstup (monitor)
gets(t); Přečte ze standardního vstupu (klávesnice) řetězec až do konce řádku
fgets(t, n, fp); Přečte ze souboru řetězec až do konce řádku (nejvýše však n-1 znaků)
puts(t); Zapíše řetězec do standardního výstupu (monitor) a přidá za něj znak "nový řádek"
fputs(t, fp); Zapíše řetězec do souboru

Přímý vstup a výstup

Přesuny bloků paměti:

fread(kam, velikost_položky, počet_položek, proud)
fwrite(odkud, velikost_položky, počet_položek, proud)

Vrací počet přenesených položek

Pomocné funkce

ferror(fp) vrací nenulu, došlo-li k chybě
feof(fp) vrací nenulu, když jsme se pokusili číst za konec souboru
fflush(fp) provede výstup nashromážděný v bufferu

Bližší identifikace chyby se získá funkcí perror nebo jako extern int errno v <errno.h>

Další funkce: clearerr ftell fseek

V/V nad rámec normy

Není v ANSI C ani v C++, ale většina překladačů umožňuje funkce nižší úrovně open creat close read write lseek (hlavičkové soubory <io.h>, <fcntl.h>). Nepoužívá strukturu FILE, ale "manipulační číslo souboru" (handle).

Na PC bývá k dispozici <conio.h> pro práci s "konzolou".


Předchozí Předchozí přednáška Další Další přednáška Hlavní stránka Hlavní stránka