为什么这段代码不能用文件流切换cin和cout?

时间:2013-10-21 11:02:07

标签: c++ ifstream cout cin ofstream

以下是两段代码。一个工作,一个不工作,我想知道为什么。我提前道歉,因为缺乏评论和糟糕的变量名称,但现在这种语言正在磨练我的齿轮。

// File1.cpp (contains relevant includes)
// Works! It writes to out.txt and appears to use in.txt correctly
int main(int argc, char* argv[]) {
    int num;
    std::ifstream in("in.txt");
    std::streambuf* cinbuf = std::cin.rdbuf();
    std::cin.rdbuf(in.rdbuf());

    std::ofstream out("out.txt");
    std::streambuf* coutbuf = std::cout.rdbuf();
    std::cout.rdbuf(out.rdbuf());

    cout << "Give me a number: ";
    cin >> num;

    std::cin.rdbuf(cinbuf);
    std::cout.rdbuf(coutbuf);

    return 0;
}

// File2.cpp (contains relevant includes)
// Does not work! Outputs nothing to out.txt.
class TestWithStdIO {
        std::streambuf* cinbuf;
        std::streambuf* coutbuf;
    public:
        TestWithStdIO(const char* inFile, const char* outFile) {
            std::ifstream in(inFile);
            cinbuf = std::cin.rdbuf();
            std::cin.rdbuf(in.rdbuf());

            std::ofstream out(outFile);
            coutbuf = std::cout.rdbuf();
            std::cout.rdbuf(out.rdbuf());
        }
        ~TestWithStdIO() {
            std::cin.rdbuf(cinbuf);
            std::cout.rdbuf(coutbuf);
        }
};

int main(int argc, char* argv[]) {
    int num;
    TestWithStdIO* ioTest = new TestWithStdIO("in.txt", "out.txt");
    cout << "Give me a number: ";
    cin >> num;
    delete ioTest;

    return 0;
}

2 个答案:

答案 0 :(得分:1)

TestWithStdIO::TestWithStdIO()中,in.rdbuf()指向的流缓冲区与in一起被销毁(即在构造函数的末尾)。

答案 1 :(得分:1)

std::[io]fstreams inoutTestWithStdIO构造函数中具有本地范围(或自动存储持续时间)。它们在函数末尾被销毁(文件关闭)及其包含的缓冲区,在cincout内留下悬空指针。

请考虑制作in的{​​{1}}和out成员,如下所示:

TestWithStdIO

如果您只有class TestWithStdIO { std::streambuf* cinbuf; std::streambuf* coutbuf; std::ifstream in_; // <-- member std::ofstream out_; // <-- member public: TestWithStdIO(const std::string& inFile, const std::string& outFile) : in_(inFile), out_(outFile) // <-- initializer list { cinbuf = std::cin.rdbuf(); std::cin.rdbuf(in_.rdbuf()); coutbuf = std::cout.rdbuf(); std::cout.rdbuf(out_.rdbuf()); } ~TestWithStdIO() { std::cin.rdbuf(cinbuf); std::cout.rdbuf(coutbuf); } }; 支持,则可能需要in(inFile.c_str())out的等效内容。

此外,正如评论中所指出的,不需要动态分配C++03实例,实际上它可能是错误的来源。只是做

TestWithStdIO