← Повернутися до лекцій

Лекція 17: Робота з файлами (Бібліотека fstream)

1. Потоки: Звідки і Куди?

Ви вже знайомі з потоками:

  • cin (Console Input) — для читання з клавіатури.
  • cout (Console Output) — для запису на екран.

Для роботи з файлами C++ пропонує спеціальну бібліотеку <fstream> (File Stream), яка дає три нові типи даних:

  1. ofstream (Output File Stream) — для запису у файл (аналог cout).
  2. ifstream (Input File Stream) — для читання з файлу (аналог cin).
  3. fstream — універсальний (читає і пише).

2. Запис у файл (ofstream)

Алгоритм простий: Відкрити → Записати → Закрити.

#include <iostream>
#include <fstream> // 1. Підключаємо бібліотеку
#include <string>
using namespace std;

int main() {
    // 2. Створюємо об'єкт потоку і відкриваємо файл
    // Якщо файлу немає — він створиться. Якщо є — він ПЕРЕПИШЕТЬСЯ (очиститься)!
    ofstream myFile("notes.txt");

    // 3. Перевіряємо, чи відкрився файл (можливо, немає прав доступу)
    if (myFile.is_open()) {
        // 4. Пишемо дані так само, як в cout
        myFile << "Це перший рядок у файлі." << endl;
        myFile << "А це число: " << 42 << endl;

        cout << "Дані успішно записані!" << endl;

        // 5. Обов'язково закриваємо файл!
        myFile.close();
    } else {
        cout << "Помилка відкриття файлу!" << endl;
    }
    return 0;
}

Після запуску цієї програми у папці з вашим проєктом з'явиться файл notes.txt.

4. Читання з файлу (ifstream)

Тут ми діємо навпаки: тягнемо дані з файлу в змінні.

Важливо: Читання йде курсором. Після прочитання першого слова курсор зупиняється перед другим.

Спосіб А: Читання по словах (оператор >>)

Ідеально для чисел та окремих слів.

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

int main() {
    ifstream file("data.txt");
    // Припустимо, там написано: 10 20 30
    
    int a, b, c;
    file >> a; // a = 10
    file >> b; // b = 20
    file >> c; // c = 30
    
    file.close();
    return 0;
}

Спосіб Б: Читання по рядках (getline)

Ідеально для тексту з пробілами.

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

int main() {
    string line;
    ifstream myFile("notes.txt");
    // Відкриваємо для читання
    
    if (myFile.is_open()) {
        // Цикл while читає файл рядок за рядком, поки не дійде до кінця (EOF)
        while (getline(myFile, line)) {
            cout << line << endl; // Виводимо прочитаний рядок на екран
        }
        myFile.close();
    } else {
        cout << "Файл не знайдено!" << endl;
    }
    return 0;
}

5. Поєднання з Класами (Збереження об'єктів)

Це найпотужніша частина. Ми можемо зберегти стан нашого "Гравця" чи "Студента" у файл, щоб завантажити його пізніше.

На жаль, не можна просто написати file << object;. Треба зберігати кожне поле окремо.

Приклад збереження гри:

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

class Player {
public:
    string name;
    int level;
    int score;

    // Метод для збереження
    void save() {
        ofstream file("savegame.txt");
        if (file.is_open()) {
            file << name << endl;
            file << level << endl;
            file << score << endl;
            file.close();
            cout << "Гру збережено!" << endl;
        }
    }

    // Метод для завантаження
    void load() {
        ifstream file("savegame.txt");
        if (file.is_open()) {
            // Важливо зчитувати у тому ж порядку, в якому записували!
            file >> name;
            file >> level;
            file >> score;
            file.close();
            cout << "Гру завантажено!" << endl;
        } else {
            cout << "Збереження не знайдено." << endl;
        }
    }
};

int main() {
    Player p;
    p.name = "Hero";
    p.level = 5;
    p.score = 1000;
    
    p.save(); // Зберігаємо гру
    
    // Пізніше...
    Player p2;
    p2.load(); // Завантажуємо збережену гру
    cout << p2.name << " рівень " << p2.level << endl;
    
    return 0;
}