Перенаправление ввода-вывода в C ++
В 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, нам необходимо сделать: -
- Получите буфер потока A и сохраните его где-нибудь
- Установите буфер потока A в буфер потока B
- При необходимости сбросить буфер потока 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