以下是两段代码。一种有效,一种无效,我想知道为什么。对于缺少注释和糟糕的变量名,我事先表示歉意,但是现在,这种语言确实使我精疲力尽。
// 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
in
和out
在TestWithStdIO
构造函数内部具有本地范围(或自动存储持续时间)。在函数的结尾,它们连同它们所包含的缓冲区一起被销毁(并关闭了文件),在cin
和cout
内留下了悬空的指针。
考虑改用in
的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
实例,实际上,它很可能是错误的来源。做就是了TestWithStdIO ioTest ("in.txt", "out.txt");