문제

어떻게 결합합니까? std::ostream 어느 쪽이든 std::cout 또는 std::ofstream 특정 프로그램 조건에 따라 개체? 이것은 여러 가지 이유로 유효하지 않지만 의미 적으로 다음과 같은 것을 달성하고 싶습니다.

std::ostream out = condition ? &std::cout : std::ofstream(filename);

나는 예외 안전하지 않은 몇 가지 예를 보았습니다. http://www2.roguewave.com/support/docs/sourcepro/edition9/html/stdlibug/34-2.html:

int main(int argc, char *argv[])
{
  std::ostream* fp;                                           //1
  if (argc > 1)
     fp = new std::ofstream(argv[1]);                         //2
  else
     fp = &std::cout                                          //3

  *fp << "Hello world!" << std::endl;                         //4
  if (fp!=&std::cout) 
     delete fp;
}

더 나은 예외 안전 솔루션을 아는 사람이 있습니까?

도움이 되었습니까?

해결책

std::streambuf * buf;
std::ofstream of;

if(!condition) {
    of.open("file.txt");
    buf = of.rdbuf();
} else {
    buf = std::cout.rdbuf();
}

std::ostream out(buf);

이는 Cout 또는 출력 파일 스트림의 기본 StreamBuf를 출력합니다. 그 후에 당신은 "아웃"에 쓸 수 있으며 올바른 목적지에 올 것입니다. 당신이 그 모든 것을 원한다면 모든 것을 원한다면 std::cout 파일로 들어가면 그렇게 할 수 있습니다

std::ofstream file("file.txt");
std::streambuf * old = std::cout.rdbuf(file.rdbuf());
// do here output to std::cout
std::cout.rdbuf(old); // restore

이 두 번째 방법에는 예외가 안전하지 않다는 단점이 있습니다. Raii를 사용하여 이것을하는 수업을 작성하고 싶을 것입니다.

struct opiped {
    opiped(std::streambuf * buf, std::ostream & os)
    :os(os), old_buf(os.rdbuf(buf)) { }
    ~opiped() { os.rdbuf(old_buf); }

    std::ostream& os;
    std::streambuf * old_buf;
};

int main() {
    // or: std::filebuf of; 
    //     of.open("file.txt", std::ios_base::out);
    std::ofstream of("file.txt");
    {
        // or: opiped raii(&of, std::cout);
        opiped raii(of.rdbuf(), std::cout);
        std::cout << "going into file" << std::endl;
    }
    std::cout << "going on screen" << std::endl;
}

이제 무슨 일이 있어도 std :: cout는 깨끗한 상태입니다.

다른 팁

이것은 예외-안전입니다.

void process(std::ostream &os);

int main(int argc, char *argv[]) {
    std::ostream* fp = &cout;
    std::ofstream fout;
    if (argc > 1) {
        fout.open(argv[1]);
        fp = &fout;
    }
    process(*fp);
}

편집 : Herb Sutter가 기사에서 이것을 해결했습니다. 스트림 스위칭 (주간 전문가).

std::ofstream of;
std::ostream& out = condition ? std::cout : of.open(filename);

C ++의 초보자이기 때문에 이것이 예외적인지는 모르겠지만 여기에 내가 보통 어떻게하는지는 다음과 같습니다.

std::ostream& output = (condition)?*(new std::ofstream(filename)):std::cout;

다음의 간단한 코드는 나에게 효과가 있습니다.

int main(int argc, char const *argv[]){   

    std::ofstream outF;
    if (argc > 1)
    {
        outF = std::ofstream(argv[1], std::ofstream::out); 
    }

    std::ostream& os = (argc > 1)? outF : std::cout;
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top