Programowanie w językach wysokiego poziomu Obsługa plików za pomocą strumieni Elektronika i Telekomunikacja, semestr III rok akademicki 2013/2014 dr inż. Paweł Myszkowski Plan zajęć a) otwieranie i zamykanie pliku b) odczyt i zapis za pomocą strumienia c) odczyt poszczególnych wierszy d) odczyt i zapis bloków danych e) poruszanie się wewnątrz pliku 2. Zadanie do wykonania 1
Oprócz standardowych funkcji fopen, fclose, fwrite, fread dostęp do plików możliwy jest także przy użyciu strumieni. Wykorzystujemy w tym celu bibliotekę fstream: #include <fstream> w której zdefiniowana jest klasa fstream, umieszczona w przestrzeni nazw std:: ::. Zmienna odwołująca się do pliku jest obiektem tej klasy. std::fstream plik; Otwieranie pliku Wykorzystujemy tu metodę open() klasy fstream: void open (const char* nazwa, ios_base::openmode tryb); (pierwszy parametr to nazwa i ścieżka do pliku, drugi tryb otwarcia) Tryb ios::app ios::ate Opis (append dopisywanie) Plik otwarty w trybie tylko do zapisu. Wskaźnik ustawiany jest na końcu pliku. (at end na końcu) Wskaźnik pliku ustawiony na końcu w chwili otwarcia pliku. ios::binary (binary binarne) Informacja dla kompilatora, aby dane były traktowane jak strumień danych binarnych ios::in ios::out ios::trunc (input wejście) Zezwolenie na odczytywanie danych z pliku (output wyjście) Zezwolenie na zapisywanie danych do pliku (truncate obcięcie) Zawartość pliku jest kasowana w chwili otwarcia 2
Tryby można ze sobą łączyć, stosując operator ' ': plik.open(" ("dane.txt",std::ios::in std::ios::out); Czy udało się otworzyć plik? Stan możemy zbadać za pomocą funkcji good() oraz is_open() bool good(); //true jeśli plik udało się otworzyć bool is_open(); //false jeśli nie Zamykanie pliku void close(); Schemat przetwarzania pliku: #include <fstream> int main() plik.open(" ("dane.txt",std::ios::in std::ios::out); if (plik.good() == true) //przetwarzanie zawartości pliku (zapis/odczyt) plik.close(); 3
Odczyt i zapis za pomocą strumienia: a) odczyt (zmienna_plikowa >> zmienna_do_której_trafią_dane) int x; plik >> x; //tak jak cin b) zapis (zmienna_plikowa << zmienna_którą_zapisujemy) int x = 5; plik << "Oto wynik: " << x << endl; //tak jak cout uwagi: - dane traktowane zawsze tekstowo, niezależnie od trybu otwarcia, - odczyt do pierwszego "białego" znaku (enter, spacja, tabulator). Odczyt poszczególnych wierszy (linii): Funkcja getline() z klasy fstream: istream & getline(char * dane, streamsize długość) plik.open(" ("dane.txt",std::ios::in std::ios::out); char dane[255]; plik.getline(dane,255); uwagi: - dane traktowane zawsze tekstowo, niezależnie od trybu otwarcia. 4
Odczyt i zapis bloku danych (dane binarne): a) odczyt istream & read (char * bufor, streamsize rozmiar); int gcount() //określa liczbę przetworzonych bajtów b) zapis ostream & write (const char * bufor, streamsize rozmiar); Przykład: plik.open(" ("dane.txt",std::ios::in std::ios::out); char bufor[255]; plik.read(bufor,1024); std::cout << "wczytano " << plik.gcount() << " bajtów"; Poruszanie się po pliku z danymi seekg() ustawienie wskaźnika dla odczytu: istream & seekg (streamoff offset, ios::base::seekdir kierunek); seekp() ustawienie wskaźnika dla zapisu: ostream & seekg (streamoff offset, ios::base::seekdir kierunek); ios_base::beg przesunięcie wzg. początku pliku ios_base:cur przesunięcie wzg. aktualnej pozycji ios_base::end przesunięcie wzg. końca pliku tellg() - odczytanie bieżącej pozycji (odczyt z pliku): streampos tellg(); tellp() - odczytanie bieżącej pozycji (zapis do pliku): streampos tellp(); 5
fail() kontrola błędu przy przesunięciu bool fail(); //zwraca true,, jeśli wystąpił błąd Przykład plik.open(" ("dane.txt",std::ios::in); plik.seekg(+2,std::ios_base::end); //do przodu o 2 wzg. końca if (plik.fail()) cout << "Błąd przesunięcia wskaźnika" << endl; eof() bada, czy osiągnięto koniec pliku bool eof(); #include<iostream> #include <fstream> #include <conio.h> using namespace std; int main() fstream plik; plik.open(" ("dane.txt", ios::in); if (plik.good()) char napis[255]; cout << "Zawartość pliku:" << endl; 6
while (!plik.eof()) plik.getline(napis,255); couit << napis << endl; plik.close(); else cout << "Błąd otwarcia pliku!" << endl; getch(); return 0; 2. Zadanie do wykonania Wykorzystaj obsługę plików za pomocą strumieni w aplikacji "okienkowej". Przetestuj dostęp do plików tekstowych i binarnych. Wykorzystaj okna dialogowe. 7
Dziękuję za uwagę 8