Obsługa plików w C++

Obsługa plików w C++

Obsługa plików oznacza odczytywanie i zapisywanie plików (takich jak .txt, .csv itp.) przy użyciu klas dostarczonych przez standardową bibliotekę C++.

  • Programy działają w pamięci RAM, co oznacza, że ​​dane istnieją tylko podczas działania programu. Po zakończeniu programu wszystkie dane w pamięci RAM są automatycznie tracone.
  • Obsługa plików umożliwia przechowywanie danych w pamięci dodatkowej (takiej jak dysk twardy lub dysk SSD), dzięki czemu można je trwale zachować oraz zapisać i uzyskać do nich dostęp nawet po zakończeniu programu.
  • Do operacji na plikach C++ udostępnia klasy strumieni plików w formacie nagłówek, taki jak ofstream ifstream fstream.

Otwieranie pliku

Przed odczytaniem lub zapisaniem pliku musimy go najpierw otworzyć. Otwarcie pliku ładuje ten plik do pamięci RAM. W C++ otwieramy plik, tworząc do niego strumień za pomocą metody fstream klasa reprezentująca strumień pliku, tj. strumień danych wejściowych i wyjściowych do pliku.

C++
   fstream     str  (  'filename.ext'       mode  );   

Gdzie

  • str: Nazwa nadana strumieniowi
  • nazwa pliku: Nazwa pliku
  • tryb : Reprezentuje sposób, w jaki będziemy korzystać z pliku.

Tryby otwierania plików

Tryb otwierania pliku wskazuje, że plik jest otwarty w celu odczytania zapisu lub dołączenia. Poniżej znajduje się lista wszystkich trybów plików w C++:

Tryb Opis
iOS::w Plik otwarty do odczytu. Jeśli plik nie istnieje, operacja otwierania kończy się niepowodzeniem.
ios::wyjście Plik otwarty do zapisu: wewnętrzny bufor strumieniowy obsługuje operacje wyjściowe.
ios::binarny Operacje są wykonywane w trybie binarnym, a nie w trybie tekstowym.
ios::zjadłem Pozycja wyjściowa zaczyna się na końcu pliku.
ios::aplikacja Wszystkie operacje wyjściowe mają miejsce na końcu pliku, który jest dołączany do jego istniejącej zawartości.
ios::trunk Cała zawartość, która istniała w pliku przed jego otwarciem, zostanie odrzucona.

Na przykład jeśli chcemy otworzyć plik do odczytu, używamy następującego trybu otwierania:

C++
   fstream     filein  (  'file.txt'       ios  ::  in  );   

Podobnie, jeśli chcemy otworzyć plik do zapisu, używamy następujących poleceń:

C++
   fstream     fileout  (  'file.txt'       ios  ::  out  );   

Tryby te można także łączyć za pomocą operatora OR (|). Na przykład możesz otworzyć strumień plików zarówno w trybie odczytu, jak i zapisu, jak pokazano:

C++
   fstream     str  (  'file.txt'       ios  ::  in     |     ios  ::  out  );   

Jeśli plik otwarty w trybie zapisu nie istnieje, tworzony jest nowy plik. Jeśli jednak plik otwarty w trybie odczytu nie istnieje, nie jest tworzony żaden nowy plik i zgłaszany jest wyjątek

Inne strumienie plików

fstream nie jest jedynym strumieniem plików udostępnianym przez C++. Istnieją dwa bardziej wyspecjalizowane strumienie:

  • jeśli strumień : Oznacza strumień pliku wejściowego. Jest to odpowiednik otwarcia fstream w iOS::w tryb.
  • poza strumieniem : Oznacza strumień pliku wyjściowego. Jest to równoznaczne z otwarciem fstream w ios::wyjście tryb.

Powyższe tryby są trybami domyślnymi dla tych strumieni. Tych trybów nie można zmieniać, ale można je łączyć z innymi trybami. Teraz jako dane wejściowe możemy również użyć ifstream, jak pokazano:

C++
   ifstream     filein  (  'file.txt'  );   

Podobnie dla wyjścia:

C++
   ofstream     fileout  (  'file.txt'  );   

Zapisz dane do pliku

Po otwarciu pliku w trybie zapisu za pomocą jednego z nich fstream Lub poza strumieniem możemy wykonać operację zapisu w podobny sposób, jak przy użyciu cout < < operator.

C++
   #include          using     namespace     std  ;   int     main  ()     {      // Open a file      ofstream     file  (  'GFG.txt'  );          // Write the string to the file      file      < <     'Welcome to GeeksforGeeks.'  ;      return     0  ;   }   
pisaćTekst GFG

Odczytaj dane z pliku

Po otwarciu pliku w trybie odczytu za pomocą fstream lub ifstream możemy wykonać operację zapisu w podobny sposób jak w przypadku cin za pomocą >> operatora.

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      file     >>     s  ;      cout      < <     'Read String: '      < <     s  ;      return     0  ;   }   


Wyjście

 Read String: Welcome  

Ma ten sam problem co cin. Dane wejściowe są pobierane tylko do pierwszego znaku odstępu. Aby tego uniknąć, możemy użyć getline() funkcja jak pokazano:

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      getline  (  file       s  );      cout      < <     'Read String: '      < <     s  ;      return     0  ;   }   


Wyjście

 Read String: Welcome to GeeksforGeeks.  

Zamykanie pliku

Zamknięcie pliku oznacza zamknięcie powiązanego strumienia i zwolnienie zasobów, których używamy. Ważne jest, aby zamknąć plik po zakończeniu pracy, szczególnie w przypadku długotrwałych programów, aby uniknąć utraty danych itp.

W C++ pliki są zamykane za pomocą metody zamknąć() funkcja członkowska, która jest obecna we wszystkich strumieniach plików.

C++
   #include          using     namespace     std  ;   int     main  ()   {      // Open a file in read mode      ifstream     file  (  'GFG.txt'  );      string     s  ;      // Read string from the file      getline  (  file       s  );      cout      < <     'Read String: '      < <     s  ;      // Close the file      file  .  close  ();      return     0  ;   }   


Wyjście

 Read String: Welcome to GeeksforGeeks.  

Błędy w obsłudze plików

Podczas obsługi plików może wystąpić wiele różnych typów błędów, np. nie znaleziono pliku, zapełniony dysk itp. Nasze programy powinny spodziewać się typowych błędów i powinny być w stanie prawidłowo je obsłużyć. Poniżej przedstawiono kilka typowych błędów, które mogą wystąpić podczas obsługi plików:

Błąd otwierania pliku

Może się zdarzyć, że plik nie zostanie otwarty z różnych powodów, np. nie istnieje, program nie ma uprawnień do jego otwarcia itp. W tym przypadku możemy skorzystać z opcji is_open() funkcja członkowska klas strumieni plików, aby sprawdzić, czy plik został pomyślnie otwarty, czy nie.

C++
   #include          using     namespace     std  ;   int     main  ()     {      fstream     file  (  'nonexistent_file.txt'       ios  ::  in  );      // Check if the file is opened      if     (  !  file  .  is_open  ())     {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      file  .  close  ();      return     0  ;   }   


Wyjście

 Error: Unable to open file!  

Błąd odczytu/zapisu danych

Innym częstym błędem jest brak odczytu lub zapisu danych z powodów takich jak nieprawidłowy tryb itp. W takim przypadku możemy sprawdzać poprawność operacji po każdej próbie odczytu/zapisu. Na przykład odczyt za pomocą funkcji getline() można sprawdzić w następujący sposób:

C++
   #include          using     namespace     std  ;   int     main  ()     {      fstream     file  (  'GFG.txt'       ios  ::  out  );      if     (  !  file  .  is_open  ())     {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      string     line  ;          // Checking if getline() read successfully or not      if     (  !  getline  (  file       line  ))      cerr      < <     'Error: Failed to read data'      < <     endl  ;      file  .  close  ();      return     0  ;   }   


Wyjście

 Error: Failed to read data  

Błąd końca pliku (EOF).

Próba odczytania pliku poza końcem może spowodować błąd EOF. Może się to zdarzyć, jeśli nie sprawdzisz końca pliku przed odczytaniem. Możemy sprawdzić EOF za pomocą eof() funkcja członkowska.

C++
   #include          using     namespace     std  ;   int     main  ()   {      ifstream     file  (  'GFG.txt'  );      if     (  !  file  .  is_open  ())      {      cerr      < <     'Error: Unable to open file!'      < <     endl  ;      return     1  ;      }      string     line  ;      while     (  getline  (  file       line  ))      cout      < <     line      < <     endl  ;      // Check for eof      if     (  file  .  eof  ())      cout      < <     'Reached end of file.'      < <     endl  ;      else      cerr      < <     'Error: File reading failed!'      < <     endl  ;      file  .  close  ();      return     0  ;   }   


Wyjście

 Reached end of file.  

Zauważ, że sprawdziliśmy również operację odczytu przed sprawdzeniem EOF jako getline() tylko wróci nullptr nawet jeśli odczyt nie powiedzie się z jakiegoś powodu.

Obsługa plików binarnych

W C++ też sobie poradzimy pliki binarne które przechowują dane w formacie surowym. Do odczytu i zapisu danych binarnych należy użyć ios::binarny flaga podczas tworzenia/otwierania pliku binarnego.

Zapisz w pliku binarnym

Aby zapisać dane do pliku binarnego, musimy najpierw otworzyć lub utworzyć plik ios::binarny tryb.

C++
   #include         #include         #include          using     namespace     std  ;   int     main  ()   {      string     str     =     'Welcome to GeeksForGeeks'  ;      // Open a binary file for writing      ofstream     file  (  'fileBin.bin'       ios  ::  binary  );      // Check if the file is open      if     (  !  file  )      {      cerr      < <     'Error opening the file for writing.'  ;      return     1  ;      }      // Write the length of the string (size) to file first      size_t     strLength     =     str  .  length  ();      file  .  write  (  reinterpret_cast   <  const     char     *>  (  &  strLength  )     sizeof  (  strLength  ));      // Write the string to the binary file      file  .  write  (  str  .  c_str  ()     strLength  );      // Close the file      file  .  close  ();      return     0  ;   }   


Wyjście

napisz BinarnyPlik binarny

Odczyt z pliku binarnego

Podobnie jak otwieramy plik w trybie binarnym, aby zapisać dane, aby odczytać dane z pliku binarnego, musimy otworzyć plik w trybie odczytu za pomocą iOS::w .

Składnia:

C++
   fstream     fileInstance  (  'fileName.bin'       ios  ::  in  |     ios  ::  binary  );   
C++
   #include         #include         #include          using     namespace     std  ;   int     main  ()   {      string     str  ;      // Open the binary file for reading      fstream     file  (  'fileBin.bin'       ios  ::  in     |     ios  ::  binary  );      // Check if the file is open      if     (  !  file  )      {      cerr      < <     'Error opening the file for reading.'  ;      return     1  ;      }      // Read the length of the string (size) from the file      size_t     strLength  ;      file  .  read  (  reinterpret_cast   <  char     *>  (  &  strLength  )     sizeof  (  strLength  ));      // Allocate memory for the string and read the data      char     *  buffer     =     new     char  [  strLength     +     1  ];     // +1 for the null-terminator      file  .  read  (  buffer       strLength  );      // Null-terminate the string      buffer  [  strLength  ]     =     ''  ;      // Convert the buffer to a string      str     =     buffer  ;      // Print file data      cout      < <     'File Data: '      < <     str  ;      delete  []     buffer  ;      file  .  close  ();      return     0  ;   }   


Wyjście

 File Data: Welcome to GeeksForGeeks  

Inne operacje na plikach

Możemy także wykonać więcej operacji, aby manipulować plikiem z naszego programu C++. niektóre z typowych operacji na plikach to:

  • Program w C++ do usuwania plików
  • Dołącz ciąg do istniejącego pliku
  • Skopiuj jeden plik do innego pliku
Utwórz quiz