以下是两段代码。一种有效,一种无效,我想知道为什么。对于缺少注释和糟糕的变量名,我事先表示歉意,但是现在,这种语言确实使我精疲力尽。

// 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;
}

最佳答案

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

考虑改用inoutTestWithStdIO成员,如下所示:

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()),则可能需要outC++03的等效项。

另外,正如评论中指出的那样,不需要动态分配TestWithStdIO实例,实际上,它很可能是错误的来源。做就是了
TestWithStdIO ioTest ("in.txt", "out.txt");

10-04 14:30
查看更多