Работа с файлами в C++: с чего начать новичку
Первая программа, которая читает и пишет файлы через fstream. Разберём открытие, проверку ошибок и построчное чтение — за 20 минут получите рабочий пример на C++17.

За 15–20 минут вы напишете программу, которая создаёт текстовый файл, записывает в него несколько строк, а потом читает их обратно и выводит на экран. Всё через стандартную библиотеку — никаких сторонних зависимостей. Код рассчитан на компилятор с поддержкой C++17 (GCC 9+, Clang 10+, MSVC 2019+), но приведённые примеры работают и на более старых стандартах, начиная с C++11.
Что нужно до начала
Проверьте, что у вас есть, прежде чем открывать редактор:
- Установленный компилятор:
g++,clang++или Visual Studio. Проверить версию GCC можно командойg++ --version. - Любой текстовый редактор или IDE — VS Code, CLion, Code::Blocks. Для старта хватит и Блокнота.
- Понимание, как скомпилировать и запустить программу из терминала. Для GCC это
g++ main.cpp -o appи затем./app(в Windows —app.exe). - Право на запись в ту папку, откуда запускаете программу. Если запускаете из системного каталога, файл может не создаться.
Для работы с файлами в C++ есть заголовок <fstream>. Он даёт три класса: std::ofstream — запись, std::ifstream — чтение, std::fstream — и то, и другое. Начнём с записи.
Шаг 1. Записываем текст в файл
Создайте файл main.cpp и вставьте туда весь код целиком:
#include <fstream>
#include <iostream>
int main() {
// Открываем файл на запись. Если файла нет — он создастся,
// если есть — содержимое будет стёрто.
std::ofstream output("notes.txt");
// Проверяем, что файл действительно открылся
if (!output.is_open()) {
std::cerr << "Не удалось открыть файл на запись\n";
return 1;
}
// Пишем как в обычный std::cout
output << "Первая строка\n";
output << "Вторая строка\n";
output << "Число: " << 42 << "\n";
// Файл закроется сам при выходе из main,
// но можно закрыть явно
output.close();
std::cout << "Готово, файл notes.txt записан\n";
return 0;
}
Скомпилируйте и запустите: g++ -std=c++17 main.cpp -o app, затем ./app. В консоли должна появиться строка «Готово, файл notes.txt записан», а рядом с программой — файл notes.txt с тремя строками внутри. Откройте его любым редактором, чтобы убедиться.
Главное правило работы с файлами: открыли — сразу проверьте, что открылось. Пропущенная проверка is_open() — источник половины ошибок у новичков, когда программа «молча ничего не делает».
Шаг 2. Читаем файл построчно
Теперь прочитаем то, что записали. Для чтения строк целиком используется std::getline, а не оператор >>: оператор останавливается на пробеле, а getline читает до конца строки.
#include <fstream>
#include <iostream>
#include <string>
int main() {
std::ifstream input("notes.txt");
if (!input.is_open()) {
std::cerr << "Не удалось открыть файл на чтение\n";
return 1;
}
std::string line;
int number = 1;
// getline возвращает поток; в условии он приводится
// к false, когда строки закончились
while (std::getline(input, line)) {
std::cout << number << ": " << line << "\n";
++number;
}
input.close();
return 0;
}
После запуска на экране появятся три пронумерованные строки из файла. Если файла notes.txt нет рядом с программой — увидите сообщение об ошибке из проверки is_open(). Это ожидаемо: сначала запустите программу из шага 1.
Чтение слов и чисел вместо строк
Если файл содержит числа или отдельные слова, разделённые пробелами, удобнее оператор >>. Он сам пропускает пробелы и переводы строк и пытается преобразовать текст в нужный тип:
#include <fstream>
#include <iostream>
int main() {
std::ifstream input("numbers.txt");
if (!input.is_open()) {
std::cerr << "Файл не открылся\n";
return 1;
}
int value;
long long sum = 0;
// Читаем числа по одному, пока чтение удаётся
while (input >> value) {
sum += value;
}
std::cout << "Сумма: " << sum << "\n";
return 0;
}
Если в файле numbers.txt лежит 10 20 30, программа выведет «Сумма: 60». Как только оператор >> встретит нечисловой текст или конец файла, цикл остановится.
Шаг 3. Дописываем в конец, а не затираем
По умолчанию std::ofstream стирает старое содержимое. Чтобы добавлять строки в конец файла, откройте его с флагом std::ios::app (append):
#include <fstream>
#include <iostream>
int main() {
// Второй аргумент — режим открытия
std::ofstream log("notes.txt", std::ios::app);
if (!log.is_open()) {
std::cerr << "Файл не открылся\n";
return 1;
}
log << "Ещё одна строка в конец\n";
return 0;
}
Запустите дважды — в notes.txt добавятся две одинаковые строки, а прежнее содержимое останется на месте.
Режимы открытия — коротко
Флаги комбинируются через |. Вот те, что нужны на старте:
| Флаг | Что делает |
|---|---|
std::ios::in | Открыть на чтение (по умолчанию для ifstream) |
std::ios::out | Открыть на запись, содержимое стирается (по умолчанию для ofstream) |
std::ios::app | Дописывать в конец, старое не трогать |
std::ios::binary | Бинарный режим — без преобразования переводов строк |
Текстовый и бинарный режим различаются на Windows: в текстовом \n превращается в пару \r\n при записи и обратно при чтении. Для обычных .txt это не мешает, для картинок и архивов используйте std::ios::binary. Бинарное чтение и запись — отдельная тема, здесь ограничимся текстом.
Если не получилось
Частые ошибки новичка и что с ними делать:
- Файл не создаётся, ошибок нет. Скорее всего, вы забыли проверку
is_open(), а прав на запись в текущей папке нет. Запустите программу из своей рабочей директории, а не изC:\Program Filesили системных каталогов. fatal error: fstream: No such file or directory. Заголовок называется<fstream>без расширения. Проверьте написание в#include.- Читается только первое слово из строки. Вы используете
input >> lineвместоstd::getline(input, line). Оператор>>обрывается на пробеле. - Программа читает файл, но выводит мусор или ничего. Файл лежит не там, откуда вы запускаете программу. Относительный путь
"notes.txt"отсчитывается от рабочей директории, а не от папки с исходником. Укажите полный путь или проверьте, где реально лежит файл. - Последняя строка теряется или дублируется в цикле. Вы проверяете
while (!input.eof())и читаете внутри. Так делать не надо: используйте условиеwhile (std::getline(input, line))— оно корректно останавливается.
Что делать дальше
Когда чтение и запись текста освоены, двигайтесь так: разберитесь с обработкой ошибок через флаги потока (fail(), bad()) и, при желании, через исключения (input.exceptions(...)). Дальше — бинарные файлы через read и write, а для путей и проверки существования файлов посмотрите <filesystem> из C++17: там есть std::filesystem::exists и удобная работа с путями вместо строк. Это следующая большая тема после базового ввода-вывода.
Проверка рекламы на риски: Что в макете вызовет вопросы ФАС: превосходные степени, сравнения, обещания результата, маркировка.
Спросить за 40 ₽Источники: std::basic_fstream — cppreference.com, std::getline — cppreference.com
Частые вопросы
Нужно ли вызывать close() вручную?
У меня старый компилятор без C++17. Заработает ли код?
Почему программа не находит файл, который точно существует?
Чем отличается std::endl от \n при записи в файл?
Как проверить, что запись прошла успешно, а не только открытие?
Что делать с русским текстом в файлах на Windows?
Материал носит информационный характер и подготовлен редакцией «Агентуры». Он не является офертой, рекламой или индивидуальной консультацией. Упомянутые продукты, компании и торговые знаки принадлежат их правообладателям. Перед принятием решений, влекущих юридические или финансовые последствия, обратитесь к профильному специалисту.