Работа с файлами в С++
Запись в файл (класс ofstream)
Приведенная ниже программа производит создание файла и запись в него строк, наподобие как делается вывод через объект
std::cout и оператор
<<.
#include <fstream> // ofstream
using namespace std;
int main(){
ofstream file_out("data.txt"); // Создаем объект и файл
int age = 23; // Переменная для вывода в файл
const char* name = "Alex"; // Переменная для вывода в файл
file_out << "My name = " << name << "\nAge = " << age; // Вывод в файл 2-х строк
file_out.close(); // Закрываем файл
}
Если потребуется дописывать в конец файла, то нужно применить при открытии файла флаг ios::app
ofstream file_out("data.txt", ios::app); // Создаем объект и файл для записи в конец файла
Чтение из файла (класс ifstream)
Для чтения из файла он должен уже быть создан и в нем должны быть символы, слова или строки - иначе ничего не вычитается.
Приведенная ниже программа производит чтение из файла и вывод на экран слов, наподобие как делается ввод через объект std::cin и оператор >>.
#include <iostream> // cout
#include <fstream> // ifstream
using namespace std;
int main(){
ifstream file_in("data.txt"); // Создаем объект file_in и открываем файл для чтения
char buf[100]; // Буфер для чтения из файла
file_in >> buf; // Чтение первого слова (до разделителя - пробела или конца строки)
cout << buf << endl; // Вывод первого слова
file_in >> buf; // Чтение второго слова
cout << buf; // Вывод второго слова
file_in.close(); // Закрываем файл file_in
}
Если требуется считать текст из файла без учета пробелов или переносов строк, используется функция read()
#include <iostream> // cout
#include <fstream> // ifstream
using namespace std;
int main(){
ifstream file_in("data.txt"); // Создаем объект и открываем файл для чтения
const int SIZE = 100; // Размер буфера и считываемых данных
char buf[SIZE]; // Буфер для чтения из файла
file_in.read(buf, SIZE); // Читаем содержимое файла в переменную buf с ограничением размера считываемых данных до SIZE
cout << buf; // Выводим содержимое переменной buf
file_in.close(); // Закрываем файл
}
Для чтения строки файла применяют функцию getline
file_in.getline(buf, SIZE); // Читаем строку из файла в переменную buf с ограничением размера считываемых данных до SIZE
Пословное чтение до конца файла
#include <iostream> // cout
#include <string> // string
#include <fstream> // ifstream
#include <windows.h> // SetConsoleOutputCP()
#include <ctime> // clock
#include <map> // map
int main(){
SetConsoleOutputCP(CP_UTF8); // Кодировка на вывод (можно 65001 или CP_UTF8)
std::ifstream file("data.txt"); // Открываем файл
std::map <std::string, int> str_ar; // Вектор для хранения строк
std::string str; // Строка для вычитывания из файла
while(file >> str){ // Читаем построчно строки в str до конца файла
str_ar[str] += 1; // Вставляем ключ-значение (слово, число вхождений)
}
for(auto var : str_ar){
std::cout << var.first << "\t" << var.second << std::endl; // Выводим слова и частоту использования
}
unsigned int end_time = clock();
std::cout << "Время выполнения " << end_time << " мс" << std::endl;
}
Построчное чтение до конца файла
#include <iostream> // cout
#include <string> // string
#include <vector> // vector
#include <fstream> // ifstream
using namespace std;
int main(){
ifstream file("input.txt"); // Открываем файл
vector <string> str_ar; // Вектор для хранения строк
string str; // Строка для вычитывания из файла
while(getline(file, str)){ // Читаем построчно строки в str до конца файла
str_ar.push_back(str); // Помещаем строку в вектор
cout << str << endl; // Выводим строку
}
}
Совмещенная запись и чтение из файла (класс fstream)
Ниже приведена программа которая создает и записывает в файл 2 строки, затем смещает указатель на начало файла и вычитывает из него первую строку.
#include <iostream> // cout
#include <fstream> // ifstream
using namespace std;
int main(){
fstream file_io("data.txt", ios::out | ios::in | ios::trunc); // Создаем файл и объект для чтения и записи (без флагов не создавался файл или не читался)
file_io << "hello\n" << "world";//Записываем 2 строки в файл
file_io.seekg(0, ios::beg); // Сбрасываем указатели на начало файла, т.к. в конце нет данных
const int SIZE = 100; // Размер буфера и считываемых данных
char buf[SIZE]; // Буфер для чтения из файла
file_io.getline(buf, SIZE); // Читаем строку из файла в переменную buf с ограничением размера считываемых данных до SIZE
cout << buf << endl; //hello
file_io.close(); // Закрываем файл
}
Флаги для классов ofstream, ifstream, fstream
По умолчанию для объекты классов создаются со следующими флагами
ofstream - ios::out
ifstream - ios::in
fstream - ios::out | ios::in
Флаги могут комбинироваться через знак |, например ios::out | ios::in | ios::trunc
Если файл открывается с флагами, то флаги по умолчанию необходимо явно указывать тоже (при необходимости)
Флаг | Назначение
-|-
ios::app | Файл открывается для записи. Старые данные не стираются, идет запись в конец файла, переместить указатель для записи на другое место нельзя.
ios::ate | Чтение - запись может идти в любом месте. Данные не стираются, после открытия файла указатель устанавливается на конец имеющихся в файле данных.
ios::binary | Файл открывается в двоичном виде
ios::in | Файл открывается для чтения. Доступен для объекта ifstream или fstream
ios::out | Файл открывается для записи, стираются старые данные. Доступен для объекта ofstream или fstream
ios::trunc | При открытии для записи, стираются старые данные.
Для потока fsream для создания файла могут понадобиться добавление одного из флагов ios::app или ios::trunc. Например один из них необходим для флагов чтения и записи, иначе файл не создастся:
ios::in | ios::out | ios::app
ios::in | ios::out | ios::trunc
Доступ по произвольному адресу
Для доступа по произвольному адресу в файле, после его открытия, служат функции устанавливающие указатель в заданную позицию файла:
istream &seekg(streamoff offset, ios_base::seekdir direction); // Применяется для чтения (потоки ifstream, fstream)
ostream &seekp(streamoff offset, ios_base::seekdir direction); // Применяется для записи (потоки ofstream, fstream)
// offset - Смещение в байтах
// direction - Позиция для установки указателя в файле. Принимает одно из значений:
ios_base::beg - Начало файла (значение по умолчанию)
ios_base::cur - Текущая позиция в файле
ios_base::end - Конец файла
Рассмотрим пример записи в файл строки и вычитывание ее с заданной позиции.
#include <iostream> // cout, endl
#include <fstream> // fstream
using namespace std;
int main(){
fstream file_io("data.txt", ios::out | ios::in | ios::trunc); // Cоздаём объект класса fstream для записи и связываем его с файлом;
if(!file_io.is_open()){ // Проверяем что файл открылся
cout << "file not open!!!\n";
}else{ // Файл открыт успешно
file_io << "01234567 89"; // Пишем в файл строку
file_io.seekg(4, ios_base::beg); // Отступаем на 4 байта (символа) от начала
char buf[100]; // Буфер для записи
file_io >> buf; // Читаем из файла данные в буфер
cout << buf; //4567 Отступили 4 байта и считали до разделителя (пробела)
file_io.close(); // закрываем файл
}
}
Узнать текущую позицию указателя в файле можно функцией streampos std::ifstream::tellg() или std::ofstream::tellp(). Пример использования:
int pos = file_io.tellg(); // Возвращает позицию отступа от начала файла в байтах для потоков ifstream и fstream
int pos = file_io.tellp(); // Возвращает позицию отступа от начала файла в байтах для потоков ofstream и fstream
2023-11-17
Понравилась страница?
Добавить в закладки
Или поделиться!
Связанные темы
Работа с файлами в языке С++, создание, открытие, чтение и запись в файлы. Примеры программ.