Operacje wejścia/wyjścia (odsłona druga) - pliki Bogdan Kreczmer ZPCiR IIAiR PWr pokój 307 budynek C3 bogdan.kreczmer@pwr.wroc.pl Copyright c 2005 2008 Bogdan Kreczmer Niniejszy dokument zawiera materiały do wykładu na temat programowania obiektowego. Jest on udostępniony pod warunkiem wykorzystania wyłacznie do własnych prywatnych potrzeb i może on być kopiowany wyłacznie w całości, razem z niniejsza strona tytułowa.
Czytanie z pliku C C++ C++ #include <stdio.h> int main() FILE wplik; char Znak; wplik = fopen( plik.txt, r ); if ( wplik!= NULL ) return 1; Znak = fgetc(wplik); while ( Znak!= EOF) printf( %c,znak); Znak = fgetc(wplik); fclose(wplik); return 1; #include <iostream> #include <fstream> using namespace std; ifstream char Strm; Znak; Strm.open( plik.txt ); Strm >> noskipws >> Znak; while ( Strm.good( ) ) cout << Znak; Strm >> Znak; Strm.close( ); #include <iostream> #include <fstream> using namespace std; ifstream Strm( plik.txt ); char Znak; Strm >> noskipws >> Znak; while ( Strm.good( ) ) cout << Znak; Strm >> Znak; Wykorzystujac klasę ifstream otwarcie pliku można dokonać poprzez konstruktor. Destruktor zaś dokonuje zamknięcia dostępu do pliku. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 1
Zapis do pliku C C++ C++ #include <stdio.h> int main() FILE wplik; #include <iostream> #include <fstream> using namespace std; #include <iostream> #include <fstream> using namespace std; wplik = fopen( plik.txt, w ); if ( wplik!= NULL) return 1; ofstream Strm; ofstream Strm( plik.txt ); fprintf(wplik, Ale fajnie! ); fclose(wplik); return 1; Strm.open( plik.txt ); Strm << Ale fajnie ; Strm.close( ); Strm << Ale fajnie ; Operacje zapisu można realizować z wykorzystaniem klasy ofstream. Konstruktor tej klasy umożliwia domyślne otwarcie pliku do zapisu. Destruktor zaś dokonuje zamknięcia dostępu do pliku. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 2
C Znaczniki dostępu C++ #include <stdio.h> int main() FILE wplik; wplik = fopen( plik.txt, a ); if ( wplik!= NULL) return 1; fprintf(wplik, Ale fajnie! ); #include <iostream> #include <fstream> using namespace std; ofstream Strm; Strm.open( plik.txt, ios::app ); fclose(wplik); return 1; Strm << Ale fajnie ; Znacznik in out app ate trunc binary Znaczenie Otwieranie pliku do odczytu (wartość domyślna dla ifstream) Otwiera plik do zapisu (wartość domyślna dla ofstream) Podczas zapisu zawsze dołacza znaki na końcu pliku. Po otwarciu pliku ustawia się na jego końcu. Usuwa poprzednia zawartość pliku. Nie zastępuje znaków specjalnych. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 3
Znaczniki a tryb dostępu w języku C ofstream Strm( plik.txt, ios::out ios::app ); Znacznik Znaczenie Tryb w C in Otwiera do odczytu (plik musi istnieć) r out Otwiera do zapisu; jeśli plik istnieje, to niszczy jego poprzednia zawartość; w jeśli zaś nie, to go tworzy. out trunc Otwiera do zapisu; jeśli plik istnieje, to niszczy jego poprzednia zawartość; w jeśli zaś nie, to go tworzy. out app Dołacza do pliku; jeśli plik nie istnieje, to go tworzy. a in out Otwiera w trybie odczytu i zapisu; wskaźnik aktualnej pozycji ustawiony r+ jest na poczatku, plik musi istnieć. in out trunc Otwiera w trybie odczytu i zapisu; kasuje wcześniejsza zawartość pliku; jeżeli plik nie istnieje, to jest tworzony. w+ Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 4
ifstream i ofstream ifstream Strm( plik.txt, ios::out ios::trunc ); W klasach ifstream oraz ostream domyślnym sposobem otwarcia pliku jest odpowiednio otwarcie do odczytu lub otwarcie do zapisu. Nie wyklucza to możliwości otwarcia pliku do zapisu w przypadku posługiwania się obiektem klasy ifstream oraz otwarcia do odczytu w przypadku obiektu klasy ofstream. Różni te klasy to, że nie maja dostępnych metod i przeciażeń operatorów, w przypadku klasy ifstream, które umożliwiaja odczyt, zaś w przypadku klasy ofstream, metod i przeciażeń operatorów, które umożliwiaja zapis. Klasa uniwersalna jest klasa fstream. Zawiera ona zarówno metody do odczytu jak też zapisu. fstream Strm( plik.txt, ios::in ); char Znak; Strm >> Znak; fstream Strm( plik.txt, ios::out ); Strm << Ale uniwersalnie ;-) ; Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 5
Stan strumienia Każdemu typowi strumienia (tzn. istream, ostream, ifstream, ofstream, itd.) przyporzadkowane sa znaczniki stanu określajace aktualny stan strumienia. Stan ten może być odczytany poprzez zestaw metod. Metoda good( ) eof( ) fail( ) bad( ) clear( ) Znaczenie Zwraca wartość true, gdy strumień jest poprawny, tzn. nie wystapił bład odczytu, ani też nie wystapił bład krytyczny. Zwraca true, gdy został napotkany znak końca pliku. Zwraca true, gdy wystapił bład, np. odczytu lub bład krytyczny, który mógł uszkodzić strumień. Zwraca true, gdy wystapił bład krytyczny, który mógł uszkodzić strumień. Czyści znaczniki stanu. fstream Strm( plik.txt, ios::in ); float Liczba; Strm >> Liczba; if ( Strm.fail( ) ) return 2; float Liczba; cin >> Liczba; if ( cin.fail( ) ) return 2; Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 6
Sprawdzanie stanu strumienia cin >> Liczba; if ( cin.fail( ) ) cin.clear( ); cin.ignore( );... Jeżeli po sprawdzeniu stanu strumienia wykryty został bład, to przed wykonaniem następnej operacji należy wyzerować znaczniki stanu strumienia. Dotyczy to wszystkich strumieni. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 7
Czytanie z pliku Plik: dane.txt Plik: wynik.txt 23 1 # ifstream IStrm( dane.txt ); ofstream OStrm( wynik.txt ); float Liczba; 24 2 # 32 31 # 12 # = while (!IStrm.eof( ) &&!IStrm.bad( ) ) if ( ( IStrm >> Liczba).good( ) ) OStrm << (Liczba+1) << endl; else OStrm << # << endl << endl; IStrm.clear( ); IStrm.ignore( ); = 33 32 # 13 # Konstrukcja tego programu zakłada, że na końcu pliku z danymi znak # musi być ostatnim znakiem. W przykładzie należy zwrócić uwagę na konieczność wykorzystania metody clear. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 8
Przeciażenia operatora << oraz >> class Wektor //...................................................... public : float x, y; Wektor( ): x( ), y( ) ; //.................................................................... ostream & operator << ( ostream &OStrm, const Wektor & W ) return OStrm << ( << W. x <<, << W. y << ) << endl; ofstream OStrm( wektor.txt ); Wektor W; OStrm << W; Utworzone przeciażenia dla klasy ostream moga być również wykorzystywane na poziomie obiektów klasy ofstream i fstream. Możliwe jest to dzięki mechanizmom dziedziczenia oraz domyślnego rzutowania typów. Analogiczne relacje występuja między klasami istream, ifstream oraz fstream. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 9
Strumień jako parametr void ZapiszDoPliku( ofstream &OStrm ) OStrm << Witaj swiecie << endl; ofstream OStrm( powitanie.txt ); ZapiszDoPliku( OStrm ); OStrm << Witaj po raz drugi << endl; Obiekt odpowiadajacy danemu strumieniowi (zarówno wejściowemu, jak też wyjściowemu) nie moga być przekazywany do funkcji/metod poprzez wartość (operacja kopiowania obiektu strumienia jest zabroniona). Można go przekazać jedynie poprzez referencję lub wskaźnik. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 10
Podsumowanie Klasy ifstream oraz ofstream dostarczaja użytecznych mechanizmów odpowiednio do czytania plików oraz zapisu do plików. W szczególności pomocnym jest to, że destruktory obiektów tych klas dokonuja zamknięcia otwartych plików. Gdy zostanie wykryty bład operacji odczytu/zapisu, to przed wykonaniem następnej operacji znaczniki stanu powinny zostać wyzerowane. Przeciażenia operatorów >> oraz << dla klas istream i ostream może być wykorzystane na poziomie obiektów reprezentujacych strumienie odpowiednio ifstream oraz ofstream. Obiekty reprezentujace strumienie nie podlegaja kopiowaniu. Z tego powodu nie moga być przekazywane do funkcji/metod poprzez wartość. Nie może dla nich również być wykonana operacja przypisania. Copyright c 2005 2008 Bogdan Kreczmer Operacje wejścia/wyjścia (odsłona druga) - pliki 11