Приклади використання засобів C++ для роботи з файлами

Приклади використання засобів C++ для роботи з файлами

У темі наведено приклади використання файлової системи C++ для:

    • читання інформації з файлів;
    • запису інформації у файли.

Зміст



1. Функція, яка читає рядки з клавіатури і записує їх у файл
#include <iostream>
#include <fstream>
using namespace std;

// Функція читає рядки з клавіатури і записує їх у файл
void Example1(const char * filename)
{
  ofstream os(filename); // текстовий файл для виведення

  // перевірка, чи файл відкрито
  if (!os)
  {
    cout << "Cannot open the file to output. \n";
    return;
  }

  char str[80];

  cout << "Save the lines to HDD. Enter ! to stop." << endl;

  do
  {
    cout << ":";

    // читання рядка з врахуванням пробілів між словами
    cin.getline(str, 80);

    os << str << endl; // записати у файл рядок str
  } while (*str != '!'); // кінець вводу рядків - !

  os.close(); // закрити файл
  return;
}

void main()
{
  Example1("myfile.txt");
}

Після виклику функції Example1() буде створено файл “myfile.txt”, в якому буде записано рядки, що були введені з клавіатури.

Результат роботи програми:

Save the lines to HDD. Enter ! to stop.
:Hello world!
:bestprog.net
:Working with files in C++
:!

 

2. Функція, яка читає текстовий файл і виводить його вміст на екран

Функція Example2() читає вміст текстового файлу filename, ім’я якого є вхідним параметром фунції.

#include <iostream>
#include <fstream>
using namespace std;

// Функція, яка читає файл filename і виводить його на екран
// Використовується клас ifstream для читання файлу
bool Example2(const char * filename)
{
  // створити екземпляр класу
  ifstream is(filename); // відкрити файл у конструкторі

  // якщо файл не відкрито, то вихід з кодом false
  if (!is)
    return false;

  // читання рядків у циклі while
  char str[100]; // буфер для читання одного рядка

  while (is) // якщо is ненульове, то ще не кінець файлу
  {
    is.getline(str, 100); // прочитати рядок з файлу в буфер str
    cout << str << endl; // вивести на екран
  }

  is.close(); // закрити файл
  return true;
}

void main()
{
  Example2("myfile.txt");
}

Результат роботи програми відображає вміст файлу “myfile.txt”, створеного у п.1 цієї теми

Hello world!
bestprog.net
Working with files in C++
!

 

3. Приклад безформатного введення/виведення. Копіювання одного файлу в інший

У прикладі реалізовано функцію Example3(), яка виконує копіювання файлів у двійковому (бінарному) форматі. Функція отримує два параметри. Перший параметр типу const char* є іменем файлу, який служить файлом-джерелом. Другий параметр типу const char* є іменем файлу, який є файлом-призначенням.
Функція реалізує посимвольне копіювання. Щоб отримати символ з файлу-джерела використовується функція get().

#include <iostream>
#include <fstream>
using namespace std;

// Безформатний ввід/вивід, копіювання одного файлу в інший
// функція, яка читає файл readFile і записує його у файл writeFile
// використовує функцію get() для читання
bool Example3(const char * readFile, const char * writeFile)
{
  // створити екземпляри класів ifstream, ofstream
  ifstream rf(readFile, ios::in | ios::binary); // файл-джерело (читання)

  // перевірка, чи відкрито файл-джерело
  if (!rf)
  {
    cout << "Cannot open source file." << endl;
    return false;
  }

  // файл-призначення (запис)
  ofstream wf(writeFile, ios::out | ios::binary);

  // перевірка, чи відкрито файл-призначення
  if (!wf)
  {
    rf.close(); // закрити файл-джерело
    cout << "Cannot open the files." << endl;
    return false;
  }

  char sym;

  // цикл посимвольного читання
  while (rf)
  {
    rf.get(sym); // зчитати з rf => sym
    if (rf)
      wf << sym; // запис sym => wf
  }

  cout << "Copy result: OK!" << endl;

  rf.close(); // закрити обидва файли
  wf.close();
}

Виклик функції Example3() з функції main() може бути наступним:

void main()
{
  Example3("myfile.txt", "myfile2.txt");
}

Після виконання функції Example3() буде створено файл “myfile2.txt”, який буде копією файлу “myfile.txt”.

 

4. Приклад безформатного введення/виведення. Копіювання одного файлу в інший. Функція put()

Функція Example4(), що реалізована у даному прикладі працює так само як і попередня (п. 3). Однак, замість виведення в потік << використовується функція put(). Також, з допомогою функції is_open() виконується перевірка на коректність відкриття файлу.

#include <iostream>
#include <fstream>
using namespace std;

// Те саме, що й Example3(), тільки для запису використовує
// функцію put()
bool Example4(const char * readFile, const char * writeFile)
{
  ifstream rf(readFile, ios::in | ios::binary);

  // перевірка, чи файл відкрито
  if (!rf.is_open())
    return false;

  ofstream wf(writeFile, ios::out | ios::binary);

  // перевірка, чи файл відкрито
  if (!wf.is_open())
  {
    rf.close(); // закрити раніше відкритий файл rf
    return false;
  }

  char sym;

  // цикл посимвольного читання
  while (rf)
  {
    rf.get(sym); // зчитати з rf => sym
    if (rf) wf.put(sym); // запис sym => wf
  }

  rf.close(); // закрити обидва файли
  wf.close();
}

void main()
{
  Example4("myfile.txt", "myfile2.txt");
}

 

5. Приклад функції, яка записує структурну змінну у файл

За даним прикладом можна реалізовувати власні функції, які будуть записувати структури чи класи у файл.
Реалізовано функцію Example5(), яка виконує запис структурної змінної типу BOOK у файл, ім’я якого є вхідним параметром. Функція Example5() використовує функцію write() для запису. Файл відкривається у двійковому форматі (ios::binary).

#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;

// Функція, яка записує структуру типу BOOK у файл,
// використовує функцію write()
struct BOOK
{
  char title[100]; // назва книги
  char author[70]; // автор
  int year; // рік випуску
  float price; // вартість книги
};

bool Example5(const char * filename)
{
  // створити структуру
  BOOK B;
  strcpy_s(B.title, "Title of book");
  strcpy_s(B.author, "Authof of book");
  B.year = 2000;
  B.price = 12.65f;

  // створити екземпляр файлу у двійковому форматі (ios::binary)
  ofstream outFile(filename, ios::out | ios::binary);

  if (!outFile) return false;

  // запис структурної змінної B у файл
  outFile.write((char*)&B, sizeof(BOOK));

  outFile.close(); // закрити файл
  return true;
}

void main()
{
  Example5("myfile3.txt");
}

 

6. Приклад читання структурної змінної з файлу

Даний приклад є продовженням попереднього прикладу з пункту 5. У прикладі у функції Example6() заповнюється значення структурної змінної типу BOOK. Отримане значення формується як вхідний параметр-посилання на тип BOOK. Також функція отримує параметром ім’я файлу для читання. Для читання структурної змінної використовується функція read().

#include <iostream>
#include <fstream>
#include <string.h>
using namespace std;

// читання структури типу BOOK з файлу filename
// використовується функція read
bool Example6(const char * filename, BOOK& B)
{
  ifstream inFile(filename, ios::in | ios::binary);
  if (!inFile) return false;

  // отримати структурну змінну B з файлу
  inFile.read((char *)&B, sizeof(BOOK));

  inFile.close();
  return true;
}

void main()
{
  BOOK B; // читання з файлу і запис в структурну змінну B
  Example5("myfile3.txt"); // запис у файл
  Example6("myfile3.txt", B); // читання з файлу

  // вивести вміст змінної B
  cout << "B.title = " << B.title << endl;
  cout << "B.author = " << B.author << endl;
  cout << "B.price = " << B.price << endl;
  cout << "B.year = " << B.year << endl;
}

Результат роботи програми

B.title = Title of book
B.author = Authof of book
B.price = 12.65
B.year = 2000

 

7. Приклад читання/запису масиву структур у файл. Функції write(), read()

У прикладі використовуються функції write(), read() для роботи зі структурою типу BOOK, а саме:

  • запис масиву типу BOOK у файл, що складається з трьох структурних змінних;
  • читання масиву структур типу BOOK з файлу.

 

#include <iostream>
#include <fstream>
#include <string>
using namespace std;

// Структура BOOK
struct BOOK
{
  char title[100]; // назва книги
  char author[70]; // автор
  int year; // рік випуску
  float price; // вартість книги
};

// Запис масиву структур в файл з допомогою функції write()
// читання масиву структур з файлу з допомогою функції read()
bool Example7(const char * filename)
{
  // продемонстровано запис в файл та читання з цього файлу масиву структур типу BOOK
  // створити масив структур
  BOOK B[3] = {
    { "Title-01", "Author-01", 2005, 100.95 },
    { "Title-02", "Author-02", 2008, 90.25 },
    { "Title-03", "Author-03", 2002, 180.50 }
  };
  int n = 3; // кількість елементів у масиві B
  BOOK C[3]; // інший масив, з якого буде виконуватись читання
  int n2; // кількість елементів у масиві C
  int i;

  // 1. Запис масив структур в файл
  // outF - екземпляр файлу, в який здійснюється запис
  ofstream outF(filename, ios::out | ios::binary);
  if (!outF) return false;

  // записать значение n
  outF.write((char*)&n, sizeof(int));

  // запис масиву B[] в файл wf
  for (i = 0; i < n; i++)
  {
    outF.write((char*)&(B[i]), sizeof(BOOK));
  }
  cout << "Array is written\n" << endl;

  // після закінчення роботи з файлом його потрібно закрити (обов'язково)
  outF.close();

  // 2. Читання масиву структур з файлу
  // inF - екземпляр файлу, з якого здійснюється читання
  ifstream inF(filename, ios::in | ios::binary);

  if (!inF) return false;

  cout << "Read the array...\n";

  // Спочатку прочитати кількість записаних структур
  inF.read((char*)&n2, sizeof(int));

  // цикл читання масиву структур в змінну C
  for (i = 0; i < n2; i++)
  inF.read((char*)&(C[i]), sizeof(BOOK));

  inF.close(); // закрити файл

  // вивід масиву C на екран
  cout << "Array C:" << endl;
  for (i = 0; i < n2; i++)
  {
    cout << "Title = " << C[i].title << ", ";
    cout << "Author = " << C[i].author << ", ";
    cout << "Year = " << C[i].year << ", ";
    cout << "Price = " << C[i].price << endl;
  }
}

void main()
{
  Example7("file7.bin");
}

 

8. Приклад запису/читання масиву чисел типу double

Демонструється:

  • запис у файл масиву M чисел типу double функцією write();
  • читання з файлу масиву чисел типу double функцією read().

Файл відкривається у двійковому форматі.

#include <iostream>>
#include <fstream>
using namespace std;

// використання функцій read(), write() для запису/читання масиву чисел
bool Example8(const char * filename)
{
  double M[] = { 2.44, 3.85, -3.23, 11.85, 3.38 }; // масив чисел
  int i;
  int n = 5; // кількість елементів у масиві M

  // 1. Запис масиву в файл
  // 1.1. Створити екземпляр outF, зв'язаний з файлом filename
  ofstream outF(filename, ios::out | ios::binary); // для запису, двійковий формат

  // 1.2. Перевірка, чи відкривається файл
  if (!outF)
  {
    cout << "Error. Cannot open the file.";
    return false;
  }

  // 1.3. Записати кількість елементів у масиві M
  outF.write((char*)&n, sizeof(int));

  // 1.4. Записати увесь масив в файл
  outF.write((char*)&M, sizeof(double)*n);
  outF.close(); // закрити файл

  // 2. Читання даних з файлу filename в масив M2
  double M2[5];
  int n2;

  // 2.1. Відкрити файл для читання
  ifstream inF(filename, ios::in | ios::binary);

  // 2.2. Перевірка чи файл відкрито
  if (!inF)
  {
    cout << "Error. Cannot open file.";
    return false;
  }

  // 2.3. Зчитати к-сть елементів у масиві
  inF.read((char*)&n2, sizeof(int));

  // 2.4. Зчитати дані з файлу в масив M2
  inF.read((char*)&M2, sizeof(double)*n2);
  inF.close(); // закрити файл

  // 2.5. Вивести масив M2 на екран
  cout << "Array M2:\n";
  for (i = 0; i < n2; i++)
    cout << M2[i] << " ";
  cout << endl;

  return true;
}

void main()
{
  Example8("file8.bin");
}

Результат роботи програми:

Array M2:
2.44 3.85 -3.23 11.85 3.38

 

9. Приклад читання з файлу рядків. Функція getline()

У функції Example9() здійснюється порядкове читання з файлу з допомогою функції getline(). Ім’я файлу задається вхідним параметром filename. Рядки у файлі складаються з набору слів, розділених символом “пробіл”.

#include <iostream>
#include <fstream>

using namespace std;

// Читання з файлу. Функція getline()
bool Example9(const char* filename)
{
  ifstream inputFile(filename);
  char buffer[255]; // буфер для зберігання одного рядка

  if (!inputFile)
  {
    cout << "Error. Cannot open file";
    return false;
  }

  // цикл читання рядків з файлу
  while (inputFile)
  {
    inputFile.getline(buffer, 255);
    if (inputFile)
      cout << buffer << endl; // вивід прочитаного рядка на екран
  }

  inputFile.close();
  return true;
}

 

10. Приклад читання рядків з файлу. Функції getline() + eof()

У прикладі реалізована функція Example10(), яка здійснює читання рядків з файлу. Файл відкривається у текстовому форматі. Ім’я файлу задається вхідним параметром функції. Визначення кінця файлу виконується з допомогою функції eof().

#include <iostream>
#include <fstream>
using namespace std;

// читання з файлу. Функції getline()+eof()
bool Example10(const char* filename)
{
  // створити екземпляр файлу filename
  ifstream inputFile(filename, ios::in);
  if (!inputFile) return false;

  char buffer[255]; // буфер для зберігання одного рядка

  // цикл читання рядків файлу
  // рядки читаються до тих пір, поки не буде досягнуто кінця файлу
  while (!inputFile.eof())
  {
    inputFile.getline(buffer, 255);
    if (inputFile)
      cout << buffer << endl;
  }

  inputFile.close();
}

 


Зв’язані теми