エンジニアのソフトウェア的愛情

または私は如何にして心配するのを止めてプログラムを・愛する・ようになったか

標準入力、標準出力、標準エラーをコードでリダイレクトする

cstdio と iostream が混ざっているのが少々座りが悪いのですが。iostream からファイルディスクリプタを取得できればよいのですが仕様上は仕組みが用意されていないようなので、cstdio を利用しています。

#ifndef REDIRECT_H__
#define REDIRECT_H__

#include <unistd.h>

template<int FD>
class RedirectT {
public:
    RedirectT(int fd) : dup_fd_(dup(FD)) {
        dup2(fd, FD);
    }

    ~RedirectT() {
        sync();
        dup2(dup_fd_, FD);
        close(dup_fd_);
    }

private:
    int dup_fd_;
};

typedef RedirectT<0> RedirectStdin;
typedef RedirectT<1> RedirectStdout;
typedef RedirectT<2> RedirectStderr;

#endif//REDIRECT_H__

使用例。

#include <iostream>
#include <cstdio>

#include "redirect.h"

int main(int, char* []) {
    {
        FILE* file = std::fopen("temp.txt", "w");
        RedirectStdout to(fileno(file));
        std::cout << "This message is redirected to file." << std::endl;
        fclose(file);
    }

    {
        FILE* file = std::fopen("temp.txt", "r");
        RedirectStdin from(fileno(file));
        std::cout << std::cin.rdbuf() << std::endl;
        fclose(file);
    }

    std::cout << "This message is not redirected to file." << std::endl;

    return 0;
}

コンパイルして実行。

$ g++ -o redirect_sample redirect_sample.cpp 
$ ./redirect_sample 
This message is redirected to file.

This message is not redirected to file.
$ cat temp.txt 
This message is redirected to file.

標準出力への文字列の出力が temp.txt への書き込みになり、標準入力からの文字列の入力が text.txt からの読み出しになっています。