2

有问题的代码:

#include <array>
#include <iostream>
#include <cstring>

int main(int argc, char *argv[])
{
    using namespace std;

    cout << "Read from file:" << endl;

    while (!cin.eof())
    {
        array<char, 16> l_array;
        cin.read(l_array.data(), l_array.size());
        cout.write(l_array.data(), cin.gcount());
    }

    cout << endl;
    cout << "Read from keyboard:" << endl;

    cin.rdbuf(cout.rdbuf());

    while (!cin.eof())
    {
        array<char, 64> l_array;
        memset(l_array.data(), 0, l_array.size());
        cin.read(l_array.data(), l_array.size());

        cout << "===== DATA =====" << endl;
        cout << l_array.data() << endl;
        cout << "================" << endl;
    }
}

这就是我运行程序的方式:

./application < file.txt

我可以毫无问题地从管道读取数据,但是当我想再次读取它时,它仍然与管道相关联。我不知道如何切换回来。我找到了可以改变它的“rdbuf”函数,但我不知道如何使用它。

我仅在您开始使用键盘切换到文件并返回到键盘时才找到示例。

喜欢这里:http ://www.cplusplus.com/reference/iostream/ios/rdbuf/

但是我没有记住streambuf,所以我不能像他们那样做。我想编写可以从文件中读取大部分数据的程序,并且仅在缺少某些内容时询问,或者只是在运行时询问用户许可或其他内容。全部在linux下的console里面。

@EDIT 谢谢你的帮助,我发布解决方案

class RedirectCinToConsole
{
    protected:
        std::ifstream m_console;
        std::streambuf *m_oldCin;
        bool m_success;

    public:
        RedirectCinToConsole() :
            m_oldCin(0),
            m_success(false)
        {
            m_console.open("/dev/tty");

            if (m_console.is_open())
            {
                m_success = true;
                m_oldCin = std::cin.rdbuf(m_console.rdbuf());
            }
        }
        virtual ~RedirectCinToConsole()
        {
            if (m_oldCin)
            {
                std::cin.rdbuf(m_oldCin);
            }
            m_console.close();
        }

        operator bool () const { return m_success; }
};

int main()
{
    RedirectCinToConsole l_redirect;
    if (l_redirect)
    {
        std::string l_helloWorld;
        std::cin >> l_helloWorld;
        std::cin.ignore();

        std::cout << l_helloWorld;
    }
    return 0;
}
4

3 回答 3

6

我突然想到,不管提出的解决方案如何,最简单的解决方案(也可能是最好的)将做相反的事情:不要重定向输入,而是将文件名传递给程序,然后让它打开std::ifstream一个阅读它,保持std::cin免费的交互式输入。

Ben Voigt 提出了标准的 Unix 解决方案,但仔细想想,上面的方法似乎更自然;它当然更容易,更便携。

于 2012-08-28T18:13:43.050 回答
3

也许您应该使用fstream创建自己的流并要求提供文件名或将文件名作为命令行参数。这将使cin其他输入操作可用。

于 2012-08-28T17:31:58.333 回答
0

尝试打开/dev/tty。这将是您的进程的关联控制台(如果有)。如果您的进程是从守护进程启动的,它可能会失败。

于 2012-08-28T17:32:12.513 回答