Перенаправление ввода-вывода в C ++

Опубликовано: 31 Декабря, 2021

В C мы могли бы использовать функцию freopen () для перенаправления существующего указателя FILE на другой поток. Прототип freopen () представлен как

 ФАЙЛ * freopen (const char * filename, const char * mode, FILE * stream);

Например, чтобы перенаправить стандартный вывод на текстовый файл, мы могли бы написать

 freopen ("text_file.txt", "w", stdout);

Хотя этот метод все еще поддерживается в C ++, в этой статье обсуждается другой способ перенаправления потоков ввода-вывода.
C ++, будучи объектно-ориентированным языком программирования, дает нам возможность не только определять наши собственные потоки, но и перенаправлять стандартные потоки. Таким образом, в C ++ поток - это объект, поведение которого определяется классом. Таким образом, все, что ведет себя как поток, также является потоком.
Объекты Streams в C ++ в основном бывают трех типов:

  • istream: объект Stream этого типа может выполнять операции ввода только из потока
  • ostream: эти объекты могут использоваться только для операций вывода.
  • iostream: может использоваться как для операций ввода, так и для операций вывода.

Все эти классы, а также классы файловых потоков, производные от классов: ios и streambuf. Таким образом, файловый поток и объекты потока ввода-вывода ведут себя одинаково.
Все объекты потока также имеют связанный член данных класса streambuf. Проще говоря, объект streambuf - это буфер для потока. Когда мы читаем данные из потока, мы не читаем их напрямую из источника, а вместо этого читаем их из буфера, который связан с источником. Точно так же операции вывода сначала выполняются в буфере, а затем буфер очищается (записывается на физическое устройство), когда это необходимо.
C ++ позволяет нам устанавливать буфер потока для любого потока. Таким образом, задача перенаправления потока просто сводится к изменению буфера потока, связанного с потоком. Таким образом, чтобы перенаправить поток A в поток B, нам необходимо сделать: -

  1. Получите буфер потока A и сохраните его где-нибудь
  2. Установите буфер потока A в буфер потока B
  3. При необходимости сбросить буфер потока A до его предыдущего буфера потока

Мы можем использовать функцию ios :: rdbuf () для выполнения двух операций.

1) stream_object.rdbuf(): Returns pointer to the stream buffer of stream_object
2) stream_object.rdbuf(streambuf * p): Sets the stream buffer to the object pointed by p

Вот пример программы ниже, чтобы показать шаги

CPP

// Cpp program to redirect cout to a file
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main()
{
fstream file;
file.open( "cout.txt" , ios::out);
string line;
// Backup streambuffers of cout
streambuf* stream_buffer_cout = cout.rdbuf();
streambuf* stream_buffer_cin = cin.rdbuf();
// Get the streambuffer of the file
streambuf* stream_buffer_file = file.rdbuf();
// Redirect cout to file
cout.rdbuf(stream_buffer_file);
cout << "This line written to file" << endl;
// Redirect cout back to screen
cout.rdbuf(stream_buffer_cout);
cout << "This line is written to screen" << endl;
file.close();
return 0;
}

Выход:

 Эта строка выводится на экран
Содержимое файла cout.txt:
Эта строка записана в файл

Примечание:
Вышеупомянутые шаги можно объединить в один шаг.

 авто cout_buf = cout.rdbuf (файл.rdbuf ())

// устанавливает стримбуфер couts и возвращает старый 
streambuffer обратно в cout_buf

Использованная литература:
CPP IOS

Хотите узнать о лучших видео и практических задачах, ознакомьтесь с базовым курсом C ++ для базового и продвинутого уровня C ++ и курсом C ++ STL для базового уровня плюс STL. Чтобы завершить подготовку от изучения языка к DS Algo и многому другому, см. Полный курс подготовки к собеседованию .
C++