如何将 cin 和 cout 重定向到文件?

新手上路,请多包涵

如何将 cin 重定向到 in.txtcoutout.txt

原文由 updogliu 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 921
2 个回答

这是您想要做的一个工作示例。阅读注释以了解代码中每一行的作用。我已经在我的电脑上用 gcc 4.6.1 测试过它;它工作正常。

 #include <iostream>
#include <fstream>
#include <string>

void f()
{
    std::string line;
    while(std::getline(std::cin, line))  //input from the file in.txt
    {
        std::cout << line << "\n";   //output to the file out.txt
    }
}
int main()
{
    std::ifstream in("in.txt");
    std::streambuf *cinbuf = std::cin.rdbuf(); //save old buf
    std::cin.rdbuf(in.rdbuf()); //redirect std::cin to in.txt!

    std::ofstream out("out.txt");
    std::streambuf *coutbuf = std::cout.rdbuf(); //save old buf
    std::cout.rdbuf(out.rdbuf()); //redirect std::cout to out.txt!

    std::string word;
    std::cin >> word;           //input from the file in.txt
    std::cout << word << "  ";  //output to the file out.txt

    f(); //call function

    std::cin.rdbuf(cinbuf);   //reset to standard input again
    std::cout.rdbuf(coutbuf); //reset to standard output again

    std::cin >> word;   //input from the standard input
    std::cout << word;  //output to the standard input
}

您可以在一行中 保存重定向 为:

 auto cinbuf = std::cin.rdbuf(in.rdbuf()); //save and redirect

这里 std::cin.rdbuf(in.rdbuf()) 设置 std::cin's 缓冲区为 in.rdbuf() 然后返回与 std::cin 关联的旧缓冲区 std::cout 或任何 也可以做到这一点。

希望有帮助。

原文由 Nawaz 发布,翻译遵循 CC BY-SA 3.0 许可协议

接受的答案显示了重定向 cincout 的正确方法。您需要构造另一个生命周期超过 cincout 的流对象。如果你想写一个类似 freopen 的函数,你可以为每个要重定向的流分配一个数组,以保存分配的流对象。

 #include <iostream>
#include <string>
#include <fstream>
#include <vector>

using namespace std;

template<typename>
    struct fstream_traits { };
template<typename CharT, typename Traits>
    struct fstream_traits<basic_istream<CharT, Traits>> { using type = basic_ifstream<CharT, Traits>; };
template<typename CharT, typename Traits>
    struct fstream_traits<basic_ostream<CharT, Traits>> { using type = basic_ofstream<CharT, Traits>; };

template <typename Stream>
void redirect(Stream& str, string filename)
{
    using fstream_type = typename fstream_traits<Stream>::type;
    static int index = std::ios_base::xalloc();
    if (str.pword(index) == nullptr)
    {
        str.pword(index)= new vector<ios_base*>{};
        str.register_callback([](ios_base::event event, std::ios_base& stream, int index) {
            if (event == ios_base::erase_event)
            {
                for (auto fs : *(vector<ios_base*>*)stream.pword(index))
                    delete fs;
                delete (vector<ios_base*>*)stream.pword(index);
            }
        }, index);
    }
    vector<ios_base*>* list = (vector<ios_base*>*)str.pword(index);
    list->push_back(new fstream_type{filename});
    str.rdbuf(dynamic_cast<fstream_type*>(list->back())->rdbuf())->~basic_streambuf();
}

int main()
{
    redirect(cout, "out.txt");
    cout << "Redirected text!";
    return 0;
}

如果您明确使用 istream / ostream 而不是 Stream ,则不需要模板和别名。

原文由 Tuff Contender 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏