Zapisywanie danych do plików tekstowych

Zapis całej zawartości Memo lub RichEdit

Komponenty Memo i RichEdit pozwalają nam za pomocą metody SaveToFile() zapisać od razu całą ich zawartość do pliku:

Unit1.cpp

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Memo1->Lines->SaveToFile("c:\\katalog\\plik.ext");
}


Unit1.cpp

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   RichEdit1->Lines->SaveToFile("c:\\katalog\\plik.ext");
}

Zapis danych "linia po linii"

Aby uzyskać większą kontrolę podczas zapisu należy skorzystać z dostępnych w języku C++ klas obsługujących zapis danych do pliku: klasa ofstream (obsługa zapisu danych do pliku) lub klasa fstream (obsługa odczytu/zapisu danych z/do pliku).

Poniższy przykład przedstawia nam przykład zapisu danych do pliku "linia po linii". Na formularzu mamy umieszczone pole Edit, tworzymy dla niego zdarzenie OnKeyDown, jeżeli w tym polu wciśniemy ENTER to jego zawartość zostanie dołączona na koniec pliku c:\katalog\plik.sav, jeżeli plik ten nie istnieje to zostanie utworzony.

Unit1.cpp

#include <fstream.h>
void __fastcall TForm1::Edit1KeyDown(TObject *Sender, WORD &Key, TShiftState Shift)
{
   //jeżeli wciśnięto klawisz ENTER
   if
(Key == VK_RETURN)
   {   
      //utworzenie obiektu outfile klasy istream z ustawieniem trybu otwarcia na dopisywanie
      
ofstream outfile("c:\\katalog\\plik.ext", ios::app);
      //jeżeli tworzenie obiektu zakończy się niepowodzeniem to przerwij operację
      if (!outfile) return;
      outfile << Edit1->Text.c_str() << endl;
      //zamykanie pliku
      outfile.close();
   }
}

Odczytywanie danych z plików tekstowych

Na początek utwórzmy na dysku c katalog katalog, a w nim plik plik.ext, który posłuży nam do nauki odczytu. Wprowadzamy do niego następujące dane (dane dokładnie tak jak poniżej) np. za pomocą Notatnika:

plik.ext

123 43 22
221
223 33
4

Odczyt danych "linia po linii"

Najprostszym sposobem na przeprowadzenie operacji odczytu z pliku "linia po linii" jest wstawienie na formularz komponentu Memo lub RichEdit (można go ukryć, jeżeli nie powinien być widoczny - Visible = false), załadowanie do niego pliku i np. wyświetlenie każdej linii w komunikacie (oczywiście wyświetlanie takich komunikatów nikomu się nie przyda, ale ma to na celu tylko przedstawienie sposobów odczytu):

Unit1.cpp

void __fastcall TForm1::Button1Click(TObject *Sender)
{
   Memo1->Lines->LoadFromFile("c:\\katalog\\plik.ext");
   for (int i = 0; i < Memo1->Lines->Count; i++)
   {
      ShowMessage(Memo1->Lines->Strings[i]);
   }
}


Należy zwrócić szczególną uwagę przy podawaniu ścieżki dostępu do pliku, ponieważ oddzielając od siebie katalogi trzeba używać PODWÓJNEGO backslasha (pojedynczy backslash jest zarezerwowany dla tzw. znaków specjalnych).

Aby uzyskać większą kontrolę podczas zapisu należy skorzystać z dostępnych w języku C++ klas obsługujących odczyt danych z pliku: klasa ifstream (obsługa odczytu danych z pliku) lub klasa fstream (obsługa odczytu/zapisu danych z/do pliku).

Unit1.cpp

#include <fstream.h>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   //bufor na linię z pliku
   char
buff[80];
   //utworzenie obiektu infile klasy ifstream
   ifstream infile("c:\\katalog\\plik.ext");
   //jeżeli tworzenie obiektu zakończy się niepowodzeniem to przerwij operację
   if (!infile) return;
   //odczyt linii i wyświetlanie ich w komunikatach, aż napotkany zostanie koniec pliku, czyli infile.eof()
   while (!infile.eof())
   {
      infile.getline(buff, sizeof(buff));
      ShowMessage(buff);
   }
   //zamykanie pliku
   infile.close();
}

Odczyt danych oddzielonych białymi znakami (ang. whitespace), czyli spacjami, tabulatorami lub znakami końca wiersza

Unit1.cpp

#include <fstream.h>
void __fastcall TForm1::Button1Click(TObject *Sender)
{
   int liczba;
   //utworzenie obiektu infile klasy ifstream

   ifstream infile("c:\\katalog\\plik.ext");
   //jeżeli tworzenie obiektu zakończy się niepowodzeniem to przerwij operację
   if (!infile) return;
   //odczyt liczb i wyświetlanie ich w komunikatach, aż napotkany zostanie koniec pliku, czyli infile.eof()
   while (!infile.eof())
   {      
      infile >> liczba;
      ShowMessage(liczba);
   }
   //zamykanie pliku
   infile.close();
}

Odczyt i zapis danych z/do plików tekstowych

Za pomocą klasy fstream możemy równocześnie realizować odczyt i zapis danych. Otworzenie pliku do odczytu i zapisu wykonuje się tak:

Unit1.cpp

fstream iofile("c:\\katalog\\plik.ext", ios::in | ios::out);