Narzędzia użytkownika

Narzędzia witryny


klasy_bazowe_dla_strumieni

Klasy bazowe dla strumieni

Wstęp

Strumienie są abstrakcyjnym pojęciem reprezentującym przestrzeń, na której wykonywawane są operacje wejścia i wejścia. Dokładniej, strumień reprezentuje źródło (bądź przeznaczenie) pewnego ciągu znaków o nieokreślonej długości.
Strumienie są zwykle powiązywane z określonym, fizycznym źródłem (bądź przeznaczeniem) ciągu znaków, jak np. plik na dysku, klawiatura czy konsola. Wynika stąd, że operacje na strumieniach są po prostu operacjami wejścia/wyjścia na wymienionych wyżej „fizycznych” urządzeń bądź programów.
Do zarządzania strumieniami w C++ wykorzystuje się standardową bibliotekę iostream.

Hierarchia

Klasa iostream dziedziczy po klasach istream (jej egzemplarzem, standardowo zdefiniowanym, jest strumień wejścia cin) i ostream (strumień wyjścia cout), które z kolei dziedziczą po klasie ios. Klasa ios dziedziczy po klasie basic_os, dla której klasą bazową jest natomiast ios_base;

Klasy

Poniżej został przedstawiony opis klas, po których dziedziczy klasa iostream. Opis nie ma być kopią dokumentacji - jest stworzony, żeby po to, żeby przedstawić funkcjonalność związaną z wykorzystaniem elementów oraz funkcji składowych klas bazowych dla iostream.

Klasa ios_base

ios_base (Input Output State) jest podstawową klasą bazową dla pojęcia strumienia i operacji z nim związnych. Dostarcza pojęcie flagi stanu formatowania, a także narzędzi do jego wykorzystania.

Spis omówionych elementów klasy ios_base

ios_base::enum iostate / /typ wyliczeniowy odpowiadający za kategorie błędów stanu strumienia
ios_base::skipws / /flagi stanów formatowania
ios_base::left
ios_base::right
ios_base::internal
ios_base::boolalpha
ios_base::dec
ios_base::oct
ios_base::hex
ios_base::showbase
ios_base::showpoint
ios_base::uppercase
ios_base::showpos
ios_base::scientific
ios_base::fixed
ios_base::unitbuf

ios_base::adjustfield maski (pola)
ios_base::basefield
ios_base::floatfield

Spis definicji omówionych metod klasy ios_base

ios_base::ftmflags setf(fmtflags flaga)
ios_base::fmtflags setf(ftmflags flaga, fmtflags nazwa_pola)
ios_base::ftmflags unsetf(fmtflags flaga)
ios_base::ftmflags flags(fmtflags flaga)
ios_base::ftmflags flags()
ios_base::streamsize width() const;
ios_base::width(streamsize());
ios_base::precision() const;
ios_base::precision(streamsize);
ios_base::io_state rdstate()
ios_base::void clear(io_state = ios::goodbit)
ios_base::void setstate(io_state stan)

Flagi

Flagi są polami zawierającymi informację tak/nie, dotyczącą formatowania.
Istnieje kilka sposób na ustawienie/zdjęć flag :

  1. użycie elementarnych funkcji składowych klasy ios_base służących do ustawiania i kasowania flag, takich jak setf() oraz unsetf().
  2. użycie funkcji składowych z klasy ios, takich jak width() i presision(), które nie ustawiają flag, lecz zmieniają towarzyszące im parametry, takie jak szerokość, prezycja itp., a także funckji składowej klasy basic_os - fill().
  3. użycie manipulatorów (specjalnych sekwencji), które są „wpuszczane” do strumienia i służą jako instrukcja zmiany sposobu formatowania.

Opis flag

ios_base::skipws

(skip white spaces) ustawienie tej flagi jest sugestią, by przyjmując znaki strumień ignorował ewentualne białe znaki (spacje, tabulatory, znaki nowej linii itp). Jeżeli ta flaga nie jest ustawiona, napotkanie białego znaku będzie równoznaczne z zasygnalizowaniem błedu strumienia. Domyślnie ta flaga jest ustawiona.

ios_base::left; ios_base::right; ios_base::internal

Trzy powyższe flagi obslugują justowanie. Justowanie polega na tym, że np. jeżeli liczba składająda się z 2 cyfr ma zostac wypisana na obszarze zajmującym 10 znaków, to może zostać wypisana z lewej strony tego obszaru (flaga left), z prawej (flaga right), bądź wyśrodkowana (flaga internal). Naturalnym jest, że jednocześnie może być ustawiona tylko jedna flaga odpowiedzialna za justowanie. Domyslnie jest to flaga right. Te trzy flagi tworzą maskę (pole) adjustfield.

Przykład (pseudokod, znak _ oznacza puste miejsce)

-42_______		//flaga left
_______-42		//flaga right
-_______42		//flaga internal
ios_base::boolalpha

Włączenie tej flagi powoduje, strumień mający wypisać zawartość zmiennej bool wynoszącą 1 (true) wypisze true, zaś jeżeli zmienna ma wartość 0 (false) strumień wypisze false. Domyślnie flaga jest wyłączona - strumień wypisuje 1 bądź 0.
Podobnie jest przy wczytywaniu do obiektów typu bool - po ustawieniu tej flagi strumień będzie spodziewać się nie liczb 1 lub 0, ale słów true lub false.

ios_base::dec; ios_base::oct; ios_base::hex

Te trzy flagi decydują o tym, czy wartości liczbowe naszego programu pojawiały się będą na ekranie w postaci dziesiątkowej (dec), szesnastkowej (hex) czy ósemkowej (oct).
Podobnie przy przyjmowaniu liczb (np. z klawiatury). Jeżeli będzie to zapis „101” to strumień może to uznać za liczbę w postaci dziesiątkowej , szesnastkowej bądź ósemkowej.
W jednej chwili tylko jedna flaga może być włączona.
Domyślnie wszystkie trzy flagi są wyłączone. Wówczas stosowana jest notacja dziesiątkowa (dec).

ios_base::showbase

Ustawienie tej flagi odpowiada żądaniu, by liczby całkowite wypisywane były tak, żeby łatwo moża było poznać to, w jakim systemie są one zapisane.
Domyślnie ta flaga nie jest ustawiona.
Przykład w postaci sformatowanej tabelki odpowiadającej sformatowanemu wyjściu:

			hex		oct		dec
flaga ustawiona 	0xa4c		077		32
flaga nieustawiona	a4c		77		32
ios_base::showpoint

Przy wypisywaniu liczb zmiennnoprzecinkowych ustawienie tej flagi powoduje, że wypisywane są zawsze nieznaczące zera i kropka dziesiętna. Jeżeli np. obowiązuje dokładność wypisywania do sześciu miejsc po kropce dziesiętnej, to liczby wypisywane są w sposób zgodny z przykładek. Domyślnie flaga ta nie jest ustawiona.

Przykład w postaci sformatowanej tabelki :

			double m = 7.14		double n = 4		int k = 4
flaga ustawiona		7.140000		4.000000		4
flaga nieustawiona	7.14			4			4
ios_base::uppercase

Ustawienie tej flagi włącza wyświetlanie niektórych formatów liczb z uwzględnieniem powiększenia ilczb oznaczających np. podstawę konsersji 'x' lub wykadnik 'e' w notacji naukowej, czyli np. liczba zapisana w formacie szesnastkowym 0x1a będzie wyświetlana jako 0X1A, zaś liczba 33e-5 będzie wyświetlana jako 33E-5.
Domyślnie ta flaga nie jest ustawiona.

ios_base::showpos

Ustawienie tej flagi powoduje, że przy wypisywaniu dodatnich liczb dziesiątkowych zostaną one poprzedzone znakiem + (plus), np. liczba 107.2 zostanie przedstawiona jako +107.2
Domyślnie ta flaga nie jest ustawiona.

ios_base::scientific; ios_base::fixed

Format wypisywanych przez strumień liczb zależy od obowiązującej w danej chwili dokładności. Domniemana wartość tej dokładności to sześć cyfr po przecinku.
Ustawienie flagi fixed sprawia, że liczby rzeczywiste będą wypisywane w postaci liczb dziesiętnych, np. double liczba = 91234567.66666666 zostanie wypisana jako 91234567.66667.
Ustawienie flagi scientific sprawia, że liczby będą wypisaywane w notacji naukowej (wykładniczej), czyli wspomniana powyzej liczba zostanie wypisana jako 9.123457e+007 (akurat obowiązuje zasada sześciu cyfr po przecinku, jako domnienanej dokładności). Strumień sam zaokrągla cechę, konkretnie jej szóste miejsce po przecinku.
Domyślnie, jeżeli nie jest ustawiona żadna z flag, wówczas sposób zastosowany przez strumień do wypisywania liczby zależeć będzie od samej liczby. Mianowicie :
- Gdy wykładnik liczby będzie mniejszy niż -4 bądź większy od obowiązującej dokładności (domyślnie jest to 6) to użyta zostanie opcja wykładnicza.
- W przeciwnym razie używana jest opcja notacji dziesiętnej

iso_base::unitbuf

Ustawienie tej flagi jest rezygnacją z tak zwanego buforowania strumienia. Strumień niebuforowany nie jest tak efektywny, jak buforowany.
Przez domniemanie ta flaga jest ustawiona.

Maski

Zwane również polem. Ich zadanie to łatwiejsze ustawienie justowania, konwersji i notacji. Zadanie maski polega na grupowaniu kilku flag i pilnoawniu, aby na raz włączona była tylko jedna.
Modyfikacji flag tworzących grupę dokonuje się za pomocą funkcji ios_base::fmtflags setf(fmtflags flaga, fmtflags nazwa_pola)

ios_base::adjustfield

Ta maska (pole) odpowiada za zagadnienie justowania, reprezentuje trzy wspomniane już flagi:
ios_base::left / / justowanie lewe
ios_base::right / / justowanie prawe
ios_base::internal / / justowanie wewnętrzne

ios_base::basefield

Ta maska (pole) odpowiada za zagadnienia typu konwersji, reprezentuje flagi:
ios_base::dec / / konwersja decymalna
ios_base::oct / / konwersja oktalna
ios_base::hex / / konwersja heksadecymalna

ios_base::floatfield

Ta maska (pole) odpowiada za typ notacji, reprezentuje flagi:
ios_base::scientific / / notacja naukowa (wykładnicza)
ios_base::fixed / / notacja zwykla

Opis metod klasy ios_base

ios_base::fmtflags setf(fmtflags ktore_flagi)

Funkcja ta umożliwia ustawienie w słowie stanu tych flag, które przysłaliśmy we wzorze jako argument. Funkcja, jako rezultat, zwraca dotychczasowy stan wszystkich flag formatowania.
Typ fmtflags jest typem flag w klasie ios_base, poglądowo można śmiało przyjąć, że jest to inna nazwa na typ int, zaś poszczególne flagi są bitami wchodzącymi w skład tego typu.

//przykład
cin.setf(ios::skipws); 	// ustawia flagę skipws odpowiadającą za ignorowanie białych znaków 
				// przez strumień wejściowy cin. Inne flagi pozostają bez zmian.
cin.setf(ios::skipws | ios::boolalpha) // ustawia jednocześnie obie flagi
ios_base::fmtflags setf(ftmflags flaga, fmtflags nazwa_pola)

Funkcją można szybko ustawić flagę należącą do grupy flag zwanej „maską” bądź „polem”. Istnieją trzy maski (opis niżej). Jedna z nich, odpowiadająca konwersji liczb to ios_base::basefield, w której skład wchodzą flagi ios_base::dec, ios_base::hex, ios_baze::oct. Flagi wchodzące w skład danej „maski” muszą być ustawione jako jedyne w grupie.
Np. mając strumień wypisujący dane w zapisie szesnastkowym, a chcąc, żeby wypisywał w zapisie dziesiątkowym, możemy zrobić np. tak

//przykład
cout.setf(ios_base::dec);
cout.unsetf(ios_base::hex);


bądź, z wykorzystaniem funkcji setf(flaga, nazwa_pola) :

//przykład
cout.setf(ios_base::dec, ios_base::basefield);	// ustawia flagę ios_base::dec, dbając o
                                                // wyłączenie pozostałych flag wchodzących 
                                                // w skład pola ios_base::basefield

Dodatkowo, omawianą funkcją można skasować wszystkie flagi należące do tego pola, powracajac do sytuacji domniemanej. Robi się to podając jako pierwszy argument wartość zero.

//przykład
cout.setf(0, ios::basefield);	// skasowanie wszystkich flag
ios_base::fmtflags unsetf(fmtflags flagi)

Funckja ta jako rezultat zwraca wartość typu fmtflags opisującą dotychczasowy stan wszystkich flag formatowania. Funkcja ta sprawia, że wybrana flaga zostaje skasowana (zdjęta), a inne zaś nietknięte.

//przykład
cin.unsetf(ios::skipws); //skasowanie flagi ios::skipws
ios_base::fmtflags flags(fmtflags zestaw)

Funkcja, jako rezultat, zwraca wartość typu fmtflags, obrazującą dotychczasoy stan wszystkich flag formatowania.
Jako argument przyjmuje zestaw funkcji, który można podać za pomocą OR-owania kilku flag. Ustawia wówczas te flagi, które mają byc ustawione (obecne w zestawie), zerując zaś pozostałe zdejmuje.
Główna różnica pomiędzy funkcją flags() a funkcjami setf() oraz unsetf() jest taka, że flags() wpływa na pozostałe flagi, nie tylko na te podane jako argument zestaw (pozostałe są wyłączana)

//przykład
cin.flags(ios_base::skipsw) 	// zdejmuje wszystkie flagi, ustawia tylko flagę 	
                                // ios_base::skipsw	
ios_base::fmtflags flags()

Zwraca wartość typu ftmflags zawierającą informację o wszystkich obecnie używanych flagach. Przydatne do sprawdzenia ustawienie jednej flagi bądź zapisu ustawień, celem późnniejszego do nich powrotu.

//przykład1
if(cout.flags() & ios_base::fixed)
	cout << "Flaga fixed jest ustawiona!";
//przykład2
ftmflags stare_ustawienia = cout.flas(); // zapisuje ustawienia flag strumienia cout
 
cout.setf(ios_base::fixed);
cout.setf(ios_base::skipsw);		// włączenie różnych flag
//		...
 
cout.flags(stare_ustawienia)		// przywrocenie poprzednich ustawien
ios_base::streamsize width() const

Funkcja ta zwraca obowiązującą właśnie szerokość pola, na którym wypisywana jest ze strumienia jakaś liczba.

ios_base::width(streamsize())

Funkcja określa minimalną szerokość pola, na którym ma być wypisana dana liczba.
Określenie tej liczby dotyczy tylko najbliższej operacji we/wy związanej ze strumieniem, dla którego zostaje ona podana.

//przykład
int liczba = 107;
cout << "Wypisz: " << liczba << "\nWypisz:";
cout.width(7);					//określenie nowej szerokości pola liczby
cout << liczba << ":" << endl;

Po uruchomieniu tego przykładu na ekranie pojawi się

//przykład	
Wypis:107:
Wypis:    107:

W przypadku wczytywania danych ustawienie szerokości funkcją width() nie ma wpływu na wczytywane liczby, zaś zmieni sposób wczytywania ciągu znaków (tekstu). Dzięki temu można np. zapobiec przekroczeniu rozmiaru tablicy przeznaczonej do przyjęcia znaków, jak w poniższym przykładzie :

//przykład
char napis[7];
cin.width(sizeof(napis));	// określenie szerokości (długości) pobieranego ciągu znaków
 
cin >> napis;

Warto zauważyć, że w powyższym przykładzie zostanie wczytanych 6 znaków, a nie 7, ponieważ C-stringi (char napis[7]) muszą posiadać na końcu znak null, który jest tam automatycznie dodawany.

ios_base::streamsize precision() const

Funkcja ta zwraca obecną dokładność wypisywania liczb zmiennoprzecinkowych.
Domyślnie ta dokładność wynosi 6.

Uwaga. Patrz flagi ios_base::fixed oraz ios_base:scientific

ios_base::streamsize precision(streamsize)

Funkcja ta przyjmuje jako argument wartość streamsize (przyjmijmy, że jest to inna nazwa typu int), która oznacza nową dokładność wypisywania liczb zmiennoprzecinkowych. Zwracana wartość jest równa starszej, zastępowanej dokładności wypisywania liczb zmiennoprzecinkowych.

//przykład
double 	x = 72.123456789;
	y = 10.55;
	z = 2;
 
cout << "Obecna dokładność = " << (cout.precision()) << endl;
cout << "Domniemany : " << "x=" << x << " y=" << y << " z=" << z << endl;
						//Wypisze x=72.1235 y=10.55 z=2
cout.precision(2);
cout << "Po zmianie : " << "x=" << x << " y=" << y << " z=" << z << endl;
						//Wypisze x=72 y=11 z=2	

Klasa basic_os

Klasa dziedzicząca po ios_base.

Spis omówionych definicji metod klasy basic_os

basic_os::char fill(char c)
basic_os::char fill()
basic_ios:: bool good() / /opis we flagach stanów
basic_ios::bool eof()
basic_ios::bool fail()
basic_ios::bool bad()

Omówienie metod klasy basic_os

basic_os::char fill(char c)

Funkcja ta zmienia znak wypełniający miejsce pozostale przy wypisywaniu liczby na pole o większej ilości znaków, niż długość liczby, np. liczba jest dwucyfrowa, a ma byc wypisana na 7 miejscach (zostało to ustalone za pomocą, więc pozostale miejsca są domyslnie wypełniane spacjami. Nowy znak dopełniający miejsce w takich przypadkach jest właśnie argumentem tej funkcji.
Wartość zwracana jest wypełniającym znakiem, obowiązującym do momentu wywołania tej funkcji.

int liczba = 1024;
cout.width(9);
cout.fill('*');
cout << "Liczba:" << liczba << ":" << endl;	

Wywolanie powyższego przykładu zaowocuje pojawieniem się na ekranie następującej sekwencji

Liczba:*****1024:
basic_os:char fill()

Funkcja ta zwraca znak używany obecnie jako wypełnienie pozostałego miejsca przy wypisywaniu liczby na pole o większej ilości znaków niż długość liczby.

Klasa ios

Klasa dziedzicząca po basic_ios.

Spis omówionych elementów składowych

ios::goodbit
ios::eofbit
ios::badbit
ios::failbit

Klasa istream

Obiekty klasy istream są strumieniami uzywanymi do odczytu i interpretacji sekwencji znakowych, które pojawiły się na wejściu strumienia (urzadzenia wejścia, dysk twardy, nasłuch poleceń sieciowego protokołu).
Klasa istream dziedziczy po klasie ios (a przez to po basic_os oraz ios_basse.

Spis omówionych definicji metod klasy istream

istream::int get()
istream::istream& get (char& c)
istream::istream& get(char* s, streamsize n)
istream::istream& get (char* s, streamsize n, char delim)
istream::istream& getline (char* s, streamsize n )
istream::istream& getline (char* s, streamsize n, char delim ) istream::streamsize gcount() const
istream::istream& ignore ( streamsize n = 1, int delim = EOF )
istream:: int peek()
istream::istream & read (char *gdzie, streamsize n)
istream::stremsize readsome(char* s, streamsize n)
istream::istream & putback(char c)
istream::istream & unget()

Omówienie metod klasy istream

istream::int get()

Pobiera jeden znak ze strumienia i zwraca jego wartosc rzutowana na typ integer.

//przyklad
char c, str[256];
ifstream is;
 
cout << "Wpisz nazwe pliku istniejacego w biezacym katalogu";
cin.get (str,256);
 
is.open (str);        // otwieranie pliku
 
while (is.good())     // petla trwajaca ile sie da
{
  c = is.get();       // pobierza znak z pliku
  cout << c;
}
 
is.close();           // zamykanie pliku
istream::istream& get (char& c)

Pobiera ze strumienia jeden znak i przechowuje go w zmiennej, do ktorej zostala podana referencja c.

istream& get(char* s, streamsize n)

Pobiera ze strumienia n-1 znakow badz pobiera je do momentu wystapienia znaku ogranicznika (domyslnie znak konca wiersza '\n') i lokuje je do tablicy rozpoczynającej się s. w momencie natrafienia na znak ogranicznika, jest on automatycznie dodawany do tablicy s.

istream& get (char* s, streamsize n, char delim)

Podobnie jak wyżej, z tymże przyjmuje znak ogranicznika w argumencie delim.

istream& get(streambuf& sb)

Pobiera ze strumienia znaki i lokuje je w buforze strumieniowym sb do momentu napotkania znaku ogranicznika (domyslnie znak konca wiersza '\n') badz znaku konca pliku.

istream& get(streambuff& sb, char delim)

Podobnie jak wyżej, z tymże przyjmuje znak ogranicznika w argumencie delim.

istream& getline (char* s, streamsize n )

Pobiera (n-1) znakow ze strumienia wejsciowego i lokuje je do tablicy rozpoczynajacej sie s.

istream& getline (char* s, streamsize n, char delim )

Pobiera (n-1) znakow ze strumienia wejsciowego badz pobiera je do momentu napotkania znaku ogranicznika delim i lokuje je do tablicy rozpoczynajacej sie s.

//przyklad
void uzyj_getline_gcout()
{
	char tab[10];
	cout << "Podaj tekst o dlugosc do 10 znakow :" << endl;
	cin.getline(tab, 10);
	cout << tab << endl <<"A operowales przed chwila na ilosci znakow wynoszacej :  " << cin.gcount() << endl;
}
istream::streamsize gcount() const

Zwraca ilość znaków wyciągniętych ze strumienia wejściowego podczas istotniej operacji pobrania z niego niesformatowanych danych.

Przyklad powyzej, z getline()

istream::istream& ignore ( streamsize n = 1, int delim = EOF )

Pobiera ze strumienia wejsciowego ilosc znakow podana przez argument n i pomija je. Pobieranie zatrzymuje sie w momencie napotkania na znak ogranicznika delim.

//przyklad 
char first, last;
 
cout << "Podaj imie i nazwisko: ";
 
first=cin.get();
cin.ignore(256,' ');
 
last=cin.get();
 
cout << "Twoje inicjaly to  " << first << last << endl;
istream:: int peek()

Odczytuje i zwraca kolejny znak ze strumienia, bez usuwania go stamtąd.

//przyklad
char c;
int n;
char str[256];
 
cout << "Wpisz liczbe lub slowo: ";
c=cin.peek();
 
if ( (c >= '0') && (c <= '9') )
{
  cin >> n;
  cout << "Wpisales liczbe  " << n << endl;
}else{
  cin >> str;
  cout << " Wpisales slowo " << str << endl;
}
istream::istream & read (char *gdzie, streamsize n)

Domeną zastosowań tej funkcji są binarne operacje wejścia - wyjścia. Wczytuje ona ze strumienia n znakow i umieszcza je do tablicy, której pierwszy element znajduje się pod adresem gdzie. Nie interesuje jej, czy wczytujemy dane binarne czy teksty. Niezależnie od tego, czy ze strumienia wyjmowane będą znaki alfanumeryczne, czy też znaki nowej linii, czy końca pliku - będą one umieszczane we wskazanym miejscu pamięci. Nadaje się np. do wczytywania danych binarnych z pliku dyskowego. W czasie przesyłania znaków ze strumienia może nastąpić bład - np. zażądaliśmy wczytania 50 znaków, a jest ich w strumieniu tylko 30. Zapali się wówczas flaga ios::eofbit. Żeby sprawdzić, ile znakow zostało wczytanych, warto użyć funkcji istream::gcount();

//przyklad
char napis[10];
 
for(int i = 0; i <10; i++) napis[i] = '0'; 	//"czyszczenie" tablicy
 
cout << "Zawartosc tablicy przed : " << napis << endl;
cout << "Wczytam tylko 4 bajty, napisz cos : ";
 
cin.read(napis, 4);
 
cout << "Wczytane bajty : " << napis << endl;
 
return 0;
istream::stremsize readsome(char* s, streamsize n)

Działa podobnie jak funkcja read(), z tymże jeżeli znaków w strumieniu jest mniej, niż zażądaliśmy, to wczytuje tylko tyle, ile ich jest, bez sygnalizacji błędu.
Zwraca ilość wczytanych znaków. Jeżeli bufor jest pusty, nic nie wczytuje i zwraca zero.

istream::istream & putback(char c)

Pozwala na włożenie z powrotem do strumienia znaku, który został z niego wyjęty. Wartym odnotowania jest fakt, że standard nie definiuje tego, co by się stało gdybyśmy spróbowali wrzucić do strumienia inny znak, niż został przed chwilą z niego wyczytany.

//przyklad
char c,z;
 
cin >> c;
 
cout << "Przeczytany c=" << c << endl;
 
cin.putback(c);
cin >> z;
 
cout << "Przeczytany z=" << z << endl;
 
return 0;
istream::istream & unget()

Rożni się od funkcji istream::putback() tym, że przyjmuje znaku, który trzeba włożyć z powrotem„ do struminia - powinien on być automatycznie rozpoznany przez strumień, przez co jest bezpieczniejsza, niż istream::putback();

Klasa ostream

Obiekty klasy ostream są strumianimy używanymi do wypisywania i formatowania sekwencji znakowych na wyjściu strumienia (ekran, plik na dysku itp).

Spis definicji omówionych metod klasy ostream

ostream::ostream & put(char c);
ostream::ostream & write(const char* s, streamsize n)

Omówienie metod klasy ostream

ostream::ostream & put(char c)

Służy do wstawienia do strumienia pojedynczego znaku c.
Zwraca jako wynik referencję do strumienia wyjsciowego, co pozwala na kaskadowe łączenie użycia tej funkcji, jak w przykładzie.
Czasami wstawienie znaków do strumienia może się nie powieść, np. podczas wstawiania znaków do strumienia płynącego do pliku dyskowego - np. dysk uległ zapełnieniu. Wówczas funkcja zwraca, zamiast refencji - zero.

char napis[] = "kocham zpr";
int i = 0;
do{
	cout.put(napis[i]).put('-');	
}while(napis[++i]);

Efektem działania podanego przekładu będzie wyświetlenie na ekranie

k-o-c-h-a-m- -z-p-r-
ostream::ostream & write(const char* s, streamsize n)

Funkcja służy do wstawienia do strumienia żądanej liczby bajtów.
Pierwszy argument jest wskaźnikiem do tablicy char, z której mają być pobrane bajty w celu wstawienia ich do strumienia. Drugi argument definiuje liczbę bajtów (począwszy od miejsca wskazywanego wskaźnikiem), które mają być wstawione do strumienia.

char napis[] = "Rembrandt";
int i = 0;
 
cout.write(napis+3, 4)	//wypisze na ekranie "bran";

Flagi stanu błędów strumienia

W każdym obiekcie klasy IOSTREAM jest znajduje się słowo odpowiadające za stan błedu strumienia. Jeżeli następuje jakiś błąd pracy strumienia - w tym słowie ustawiany jest bit odpowiadający za daną kategorię blędu. Te kategorie błędów określone są typem całkowitym zdefiniowanym w klasie ios_base :

ios_base::enum iostate

ios_base::enum iostate
{ goodbit = 0,
eofbit = 1,
failbit = 2,
badbit = 4
};

ios::goodbit

Wartość tego bitu wynosi 0, czyli nie jest to żadna flaga błedu. Stan goodbit jest wtedy, kiedy wszystkie pozostałe flagi są wyzerowane.

ios::eofbit

Flaga ta ustawiana jest wtedy, gdy podczas czytania napotkany został koniec pliku (EOF)

ios::failbit

Ustawienie tej flagi oznacza, że jakaś operacja we/wy nie powiodła się. Strumień tkwi w stanie błędu, jednak po wyzerowaniu tej flagi nadaje się do pracy.

ios::badbit

ustawienie tej flagi oznacza, że nastąpił jakiś powazny błąd naruszający budowę samego strumiania. Dalsza praca z tym strumieniem nie jest już możliwa.

Funkcje do pracy na flagach błędu

Funkcje te są metodami klasy BASIC_IOS, która jest bezpośrednio pochodna po klasie IOS_BASE, zaś jest bazową klasą dla IOS, dlatego każdy obiekt klasy IOSTREAM posiada dostęp do tych funkcji.

Spis definicji omówionych funkcji do pracy na flagach błędu

basic_ios:: bool good();
basic_ios::bool eof();
basic_ios::bool fail();
basic_ios::bool bad();

Omówienie funkcji do pracy na flagach błędu

basic_ios:: bool good()

Zwraca wartość true, jeżeli wszystko jest w porządku, czyli żaden z bitów błędu nie jest ustawiony, np.

char znak;
do{
	cin >> znak;
	cout << znak;	
}while(cin.good());

Powyższa pętla będzie się wykonywała dopóki nie nastąpi błąd strumienia cin.

basic_ios::bool eof()

Zwraca wartość true, jeżeli jest ustawiona flaga IOS::eofbit, czyli przy operacji wczytywania został napotkany koniec pliku, np.

char dane[1000];
ifstream s("wtorek.tmp", ios::in | ios::binary); //zakladamy istnienie pliku wtorek.tmp w katalogu, 
                                                //w ktorym znajduje sie plik wykonywalny
s.read(dane, sizeof(dane));
if(s.eof())
  cout << "Napotakny EOF przed wczytaniem wszystkich danych" << endl;
else
  cout << "Wszystkie dane wczytane O.K"
basic_ios::bool fail()

Zwraca wartość true, gdy failbit lub badbit są ustawione.

int liczba;
cin >> liczba;
if(cin.fail())
  cout << "Zle podana liczba !!" << endl;

Powyższy przykład pozwala na wychwycenie złego (nieoczekiwanego) ciągu znaków w strumieniu, np. tekstu w momencie oczekiwania na liczbę.

basic_ios::bool bad()

Zwraca wartość true, gdy flaga badbit jest ustawiona, czyli w momencie poważnego uszkodzenia strumienia.

Ręczne ustawianie i kasowanie flag błędu strumienia

Robimy to wtedy, gdy sami chcemy zdecydować o tym, co jest popawną, a co niepoprawną operacją we/wy. Przydaje się to w przypadku operacji we/wy z obiektami typu zdefiniowanego przez użytkownika.

w klasie IOS_BASE znajdują się następujące funkcje przydatne przy omawianym zagadnieniu :

ios_base::io_state rdstate();
ios_base::void clear(io_state = ios::goodbit);
ios_base::void setstate(io_state stan);

ios_base::io_state rdstate()

Zwraca jako rezultat słowo typu io_state obrazujące stan flag błędu danego strumienia.

if(cin.rdstate() & ios:failbit)
  cout << "Flaga failbit jest ustawiona" << endl;

Potega funkcji rdstate() tkwi w możliwości całościowego poznania biężącego słowa stanu, które następnie można modyfikować, np. za pomocą funkcji clear().

ios_base::void clear(io_state = ios::goodbit)

Działanie tej funkcji jest takie, że argument będący słowem stanu błędów strumienia (io_state) zastępuje całkowicie dotychczasowe słowo stanu błędów strumienia, wszystkie flagi na raz. Wartość domniemana oznacza, że w nowym słowie żadna flaga błędu nie jest ustawiona.

//przyklad
cin.clear(0);		//kasuje wszystkie flagi błędu
cin.clear();		//kasuje wszystkie flagi błędu
cin.clear(ios::eofbit);	//ustawia w strumieniu cin flagę eofbit, kasując inne
cin.clear(ios::eofbit | ios::failbit);// ustawia w strumieniu flagi eofbit i 						   
                                    // failbit	
//przyklad2
io_state slowo_stanu;
slowo_stanu = wejscie.rdstate(); //odczytanie dotychczasowego stanu
 
slowo_stanu |= ios::eofbit; 	//"dopalenie" flagi ios::eofbit
wejscie.clear(slowo_stanu);	//"podrzucenie" noweo slowa stanu

Powyzszy przyklad dokleja flage ios::eofbit do bieżącego słowa stanu

ios_base::void setstate(io_state stan)

Funkcja ta ułatwia „dopalenie” jednej flagi do biężącego słowa stanu. Jej definicja to:

//definicja
void setstate(io_state f)
{
	clear(rdstate() | f);
}
klasy_bazowe_dla_strumieni.txt · ostatnio zmienione: 2008/12/14 21:23 przez siemionides