C 언어에서는 freopen() 함수를 사용하여 입출력을 리디렉션할 수 있습니다. 이 함수를 활용하면 기존의 FILE 포인터를 다른 스트림으로 재지정할 수 있습니다. freopen의 기본 문법은 다음과 같습니다.
FILE *freopen(const char* filename, const char* mode, FILE *stream)
C++에서의 스트림 리디렉션
C++ 역시 동일하게 리디렉션이 가능합니다. 다만 C++은 스트림(stream) 개념을 기반으로 작동하며, 사용자가 직접 만든 스트림뿐만 아니라 시스템 스트림도 리디렉션할 수 있다는 점이 특징입니다. C++의 스트림은 크게 세 가지 유형으로 나뉩니다.
- istream : 입력 전용을 지원하는 스트림
- ostream : 출력 전용을 지원하는 스트림
- iostream : 입력과 출력을 모두 지원하는 스트림
이 클래스들과 파일 스트림 클래스는 모두 ios 및 streambuf 클래스로부터 파생됩니다. 따라서 파일 스트림 객체와 일반 입출력 스트림 객체는 유사한 방식으로 동작합니다.
스트림 버퍼 교체를 통한 리디렉션 원리
C++에서는 어떤 스트림에든 원하는 스트림 버퍼를 설정할 수 있습니다. 이를 활용하면 특정 스트림에 연결된 버퍼만 교체하여 손쉽게 리디렉션을 구현할 수 있습니다. 예를 들어 두 개의 스트림 A와 B가 있고, 스트림 A를 스트림 B로 리디렉션하고 싶다면 아래 단계를 따르면 됩니다.
- 스트림 A의 버퍼를 가져와 백업으로 저장한다
- 스트림 A의 버퍼를 스트림 B의 버퍼로 교체한다
- 필요하다면 스트림 A의 버퍼를 원래 상태로 복원한다 (선택 사항)
예제 코드
아래 코드는 cout 출력을 콘솔 대신 파일로 리디렉션한 후, 다시 원래 콘솔 버퍼로 복원하는 과정을 보여줍니다.
#include <fstream>
#include <iostream>
#include <string>
using namespace std;
int main() {
fstream fs;
fs.open("abcd.txt", ios::out);
string lin;
// 스트림 버퍼 백업
streambuf* sb_cout = cout.rdbuf();
streambuf* sb_cin = cin.rdbuf();
// 파일 스트림 버퍼 가져오기
streambuf* sb_file = fs.rdbuf();
// cout이 파일을 가리키도록 변경
cout.rdbuf(sb_file);
cout << "This string will be stored into the File" << endl;
// 백업해 둔 원래 버퍼 복원
cout.rdbuf(sb_cout);
cout << "Again in Cout buffer for console" << endl;
fs.close();
}실행 결과 (콘솔)
Again in Cout buffer for console
abcd.txt 파일 내용
This string will be stored into the File
실행 결과에서 확인할 수 있듯이, rdbuf() 메서드를 통해 버퍼를 교체하면 cout의 출력이 콘솔 화면 대신 텍스트 파일에 기록됩니다. 이후 백업해 둔 원래 버퍼를 다시 설정하면 출력이 정상적으로 콘솔로 돌아오는 것을 알 수 있습니다. 이러한 기법은 로그 파일 생성, 테스트 자동화, 디버깅 등 다양한 상황에서 유용하게 활용됩니다.