Strona główna » Kursy » Kurs C++ » Dane z pliku: klasa fstream
 

Dane z pliku: klasa fstream

Otwieranie pliku

Do tej pory w celu otworzenia pliku do odczytu lub zapisu wystarczyło zapisać:

  1. open("plik.txt");

Jednak można też otwierać plik w konkretnym trybie i wtedy prócz nazwy pliku podajemy dodatkowy argument, np.:

  1. open("plik.txt", ios::in);

W ten sposób zostały zadeklarowane, że w otwieranym pliku plik.txt będą zapisywane dane. Wszystkie dostępne tryby przedstawia tabelka:

TrybZnaczenie
ios::inOtwiera plik do zapisu
ios::outOtwiera plik do odczytu
ios::binaryOtwiera plik w trybie binarnym
ios::ateRozpoczyna przeglądanie pliku od ostatniego znaku
ios::appWszystkie operacje zapisu są przeprowadzane na końcu pliku. Nie zmienia dotychczasowej zawartości pliku
ios::truncJeśli plik istniał to jego zawartość zostaje zastąpiona nową

W przypadku, gdy chcemy użyć kilku trybów naraz to możemy użyć operatora binarnego OR (|):

  1. open("plik.txt", ios::in | ios::trunc);

fstream

fstream to klasa, która pozwala na odczytywanie lub zapisywanie danych z pliku. Dotychczas poznane klasy ostream i ifstream to podklasy fstream. W przypadku tych dwóch klas przypisywany jest odpowiednio domyślnie tryb ios::out i ios::in.

Spróbujmy uzyskać strumień odczytu przy pomocy fstream:

  1. fstream file;
  2. file.open("plik.txt", ios::in);

jest to równoważne z:

  1. ifstream file;
  2. file.open("plik.txt");

Przydatne funkcje

FunkcjaZnaczenie
open(name, mode)Otwiera plik o podanej nazwie i w podanym trybie
is_open()Sprawdza czy strumień jest aktywny
good()Sprawdza czy nie ma błędów w odczycie
eof()Sprawdza czy odczyt się zakończył tj. osiągnął koniec pliku
bad()Sprawdza czy nie wystąpił błąd przy zapisie
close()Zamyka strumień odczytu / zapisu

Zamiast deklaracji i open()

Dla skrótowców istnieje konstruktor, który pozwala otworzyć plik w konkretnym trybie. Ma on postać fstream [nazwa_zmiennej] ([nazwa_pliku], [tryb]). Przykładowo:

  1. std::fstream file ("plik.txt", ios::in | ios::trunc);

Oczywiście na koniec taki strumień należy zamknąć używając close().

Zadanie

Napisz aplikację, która:

  1. zapisze do pliku cyfry od 0 do 9 rozdzielone znakiem nowej linii
  2. program odczyta ten plik i wypisze zawartość na konsole
  3. dopisze na koniec pliku liczbę 10
  4. program ma wypisać na konsole największą liczbę w pliku

Rozwiązanie

Poniżej znajduje się wyjaśnienie jak napisać kod realizujący zadanie.

  1. int main () {
  2.   fstream file;
  3.   file.open ("plik.txt", ios::out);
  4.   if (file.is_open()){
  5.     for(int i = 0; i < 10; i++){
  6.       file << i << endl;
  7.     }
  8.   }
  9.   file.close();

(2.) Deklaracja zmiennej i (3.) otwarcie strumienia do zapisu. Następnie (4. - 8.) w pętli do pliku są zapisywane liczby od 0 do 9. (9.) Na sam koniec uchwyt do pliku jest zamykany.

  1.   file.open ("plik.txt", ios::in);
  2.   if (file.is_open()){
  3.     int t;
  4.     while(true){
  5.       file >> t;
  6.       if( file.eof() ) break;
  7.       cout << t << endl;
  8.     }
  9.   }
  10.   file.close();

Drugi etap polega na wczytaniu danych, więc (10.) teraz plik jest otwierany w trybie odczytu. (11.) Jeśli otwarcie się powiodło to: (12.) po zadeklarowaniu zmiennej można (13. - 17.) odczytać wszystkie dane, aż wszystkie zostaną odczytane. (19.) Na koniec etapu ponownie strumień zostaje zamknięty.

  1.   file.open ("plik.txt", ios::out | ios::app);
  2.   if (file.is_open()){
  3.     file << 10;
  4.   }
  5.   file.close();

Trzecia część kodu to powtórzenie pierwszej części, ale tym razem (20.) należy pamiętać, że liczba ma zostać dopisana. (21.) Jeśli strumień zostanie otwarty to (22.) liczba 10 zostaje dopisana i (23.) strumień zostaje zamknięty.

  1.   file.open ("plik.txt", ios::in);
  2.   if (file.is_open()){
  3.     int t, max = INT_MIN;
  4.     while(!file.eof()){
  5.       file >> t;
  6.       if(t >= max) max = t;
  7.     }
  8.     cout << "\nMax. liczba: " << max;
  9.   }
  10.   file.close();
  11.   system("pause");
  12.   return 0;
  13. }

Ostatni, czwarty etap polega na znalezieniu maksymalnego elementu w pliku. Jest to etap bardzo podobny do drugiego, ale (27. - 30.) w trakcie odczytywania należy na bieżąco interpretować odczytane dane, ponieważ po odczycie kolejnej liczby nie można pobrać wartości poprzedniej.

Zadania

Zadanie 1

Napisz aplikację, która: