문제

ANSI C ++에서 Cout 스트림을 변수 이름으로 어떻게 지정하려면? 내가하고 싶은 것은 사용자가 출력 파일 이름을 지정한 경우 출력을 전송하는 경우 화면으로 보내는 것입니다. 그래서 :

ofstream outFile;
if (outFileRequested) 
    outFile.open("foo.txt", ios::out);
else
    outFile = cout;  // Will not compile because outFile does not have an 
                     // assignment operator

outFile << "whatever" << endl;

나는 이것을 거시적 기능으로 시도했다 :

#define OUTPUT outFileRequested?outFile:cout

OUTPUT << "whatever" << endl;

그러나 그것은 나에게 컴파일러 오류를 주었다.

나는 모든 출력에 대해 if-then 블록을 사용할 수 있다고 생각했지만 가능하다면 피하고 싶습니다. 어떤 아이디어?

도움이 되었습니까?

해결책

참조를 사용하십시오. 참조는 유형이어야합니다 std::ostream, 아니다 std::ofstream, 부터 std::cout 이다 std::ostream, 따라서 가장 일반적인 분모를 사용해야합니다.

std::ofstream realOutFile;

if(outFileRequested)
    realOutFile.open("foo.txt", std::ios::out);

std::ostream & outFile = (outFileRequested ? realOutFile : std::cout);

다른 팁

귀하의 프로그램이 표준 UNIX 도구처럼 동작한다고 가정합니다. 파일이 주어지지 않으면 표준 출력에 쓸 수 있으며 파일이 주어지면 해당 파일에 쓸 것입니다. 리디렉션 할 수 있습니다 cout 다른 스트림 버퍼에 쓰기 위해. 리디렉션이 살아있는 한, Cout에 쓰여진 모든 것이 지정된 목적지에 투명하게 기록됩니다. 리디렉션 객체가 범위를 벗어나면 원래 스트림이 끼고 출력이 화면에 다시 씁니다.

struct CoutRedirect { 
    std::streambuf * old; 
    CoutRedirect():old(0) {
        // empty
    }

    ~CoutRedirect() {
        if(old != 0) {
            std::cout.rdbuf(old);
        }
    }

    void redirect(std::streambuf * to) {
        old = std::cout.rdbuf(to);
    }
}

int main() {
    std::filebuf file;
    CoutRedirect pipe;
    if(outFileRequested) {
        file.open("foo.txt", std::ios_base::out);
        pipe.redirect(&file);
    }
}

이제 Cout은 파이프가 메인에 살아있는 한 파일로 리디렉션됩니다. 복사 할 준비가되지 않았기 때문에 COPYINE를 사용하여 더 "생산 준비"로 만들 수 있습니다. 사본이 범위를 벗어나면 이미 원래 스트림을 복원합니다.

이 작업을 수행하는 방법에 대한 자세한 설명을 찾을 수 있습니다.http://groups.google.com/group/comp.lang.c+ //msg/1d941c0f26ea0d81?pli=1

스택 오버플로가 포인트를 가져 오기 위해 누군가가 이것을 더 명확하게 작성하기를 바랍니다.

수행원 Adam RosenfieldTRACKS의 트랙이지만 Ternary 및 Comma 연산자의 참조 초기화 문제를 수정 :

bool outFileRequested = false;

std::ofstream realOutFile;
std::ostream & outFile = outFileRequested
    ? realOutFile.open("foo.txt", std::ios::out), realOutFile
    : std::cout;

outFile << "some witty remark";

(VS에서 테스트)

Adam이 올바른 길을 가고 있다고 생각하지만 참조를 할당 할 수는 없다고 생각합니다. 대신 포인터를 사용해야합니다.

std::ofstream realOutFile;
std::ostream * poutFile;

if(outFileRequested)
{
    realOutFile.open("foo.txt", std::ios::out);
    poutFile = &realOutFile;
}
else
    poutFile = &std::cout;

그런 다음 참조를 포인터의 가치로 정의 할 수 있지만 전역은 아닙니다.

std::ostream & outFile = *poutFile;

나는 당신이 cout를 유형의 스트림 유형에 할당 할 수 있는지 확실하지 않습니다. Cout은 Type Ostream의 대상이며 (Cin은 Type Istream이라는 반면) 하나는 다른 하나와 상속되는지 확실하지 않습니다. 따라서 파일이 제공/존재하는지 확인하고 적절한 스트림 유형을 만드는 것이 더 나은 접근 방식 일 것입니다.

이것은 얻는 데 약 2 시간이 걸렸습니다. 기본적으로 테스트 스위트를 실행하는 외부 클래스가 있습니다. 테스트를 실행하기 위해 대의원을 보내므로 출력에 액세스하려면 출력 스트림을 보내야합니다. 테스트 당 다른 스트림을 할 수 있다고 생각합니다. 어쨌든, 나는 나중에 사용하기 위해 스트림을 통과하고 싶었습니다.

// Main code to create Test Suite Object
ofstream debugFile("debug.txt");
TestSuiteObject* myTestSuite = new TestSuiteObject(&debugFile);

// Test Suite Object
class TestSuiteObject: public Test::Suite
{
public:
 TestSuiteObject(std::ofstream* debug) : m_debug(*debug)
 {
  m_debug << "some witty remark" << std::endl;
  TEST_ADD(TestSuiteObject::test1);
  TEST_ADD(TestSuiteObject::test2);
  TEST_ADD(TestSuiteObject::test3);

 }

 void test1();
 void test2();
 void test3();

private:
 std::ofstream& m_debug;
};
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top