Потоки для работы с текстовыми файлами представляют объекты, для которых не задан режим открытия ios::binary.
Для записи в файл к объекту ofstream или fstream применяется оператор << (как и при выводе на консоль):
#include <iostream>
#include <fstream>
int main()
{
std::ofstream out; // поток для записи
out.open("hello.txt"); // открываем файл для записи
if (out.is_open())
{
out << "Hello World!" << std::endl;
}
out.close();
std::cout << "File has been written" << std::endl;
}
Здесь предполагается, что файла "hello.txt" располагается в одной папке с файлом программы. Данный способ перезаписывает файл заново. Если надо дозаписать текст в конец файла, то для открытия файла нужно использовать режим ios::app:
std::ofstream out("hello.txt", std::ios::app);
if (out.is_open())
{
out << "Welcome to C++" << std::endl;
}
out.close();
Если надо считать всю строку целиком или даже все строки из файла, то лучше использовать встроенную функцию getline(), которая принимает поток для чтения и переменную, в которую надо считать текст:
#include <iostream>
#include <fstream>
#include <string> // для std::getline
int main()
{
std::string line;
std::ifstream in("hello.txt"); // окрываем файл для чтения
if (in.is_open())
{
while (std::getline(in, line))
{
std::cout << line << std::endl;
}
}
in.close(); // закрываем файл
}
Также для чтения данных из файла для объектов ifstream и fstream может применяться оператор >> (также как и при чтении с консоли):
#include <iostream>
#include <fstream>
#include <vector>
struct Point
{
Point(double x, double y): x{x}, y{y} {}
double x;
double y;
};
int main()
{
std::vector<Point> points{ Point{0, 0}, Point{4, 5}, Point{-5, 7}};
std::ofstream out("points.txt");
if (out.is_open())
{
// записываем все объекты Point в файл
for (const Point& point: points)
{
out << point.x << " " << point.y << std::endl;
}
}
out.close();
std::vector<Point> new_points;
std::ifstream in("points.txt"); // окрываем файл для чтения
if (in.is_open())
{
double x, y;
while (in >> x >> y)
{
new_points.push_back(Point{x, y});
}
}
in.close();
for (const Point& point: new_points)
{
std::cout << "Point X: " << point.x << "\tY: " << point.y << std::endl;
}
}
Здесь вектор структур Point записывается в файл.
for (const Point& point: points)
{
out << point.x << " " << point.y << std::endl;
}
При чем при записи значений переменных файл они отделяются пробелом. В итоге будет создаваться файл в формате
0 0 4 5 -5 7
Используя оператор >>, можно считать последовательно данные в переменные x и y и ими инициализировать структуру.
double x, y;
while (in >> x >> y)
{
new_points.push_back(Point{x, y});
}
Но стоит отметить, что это ограниченный способ, поскольку при чтении файла поток in использует пробел для отделения одного значения от другого и таким образом считывает эти значения в переменные x и y. Если же нам надо записать и затем считать строку, которая содержит пробелы, и какие-то другие данные, то такой способ, конечно, не сработает.