有问题的代码:
#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所以我不能像他们那样做。我想编写可以从文件中读取大部分数据的程序,只在缺少某些内容时询问,或者只是在运行时向用户询问有关permision的内容。 linux下的所有内部控制台。
@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;
}
答案 0 :(得分:6)
在我看来,无论提出的解决方案如何,最简单的方法
解决方案(可能是最好的)就是做相反的事情:
不要重定向输入,但将文件名传递给程序,然后让
它会打开std::ifstream
来阅读它,让std::cin
免费
互动输入。
Ben Voigt提出了标准的Unix解决方案,但是还在思考 关于它,似乎上面更自然;这肯定更容易 更便携。
答案 1 :(得分:3)
也许您应该使用fstream
创建自己的流,并要求提供文件名或将文件名作为命令行参数。这将使cin
可用于其他输入操作。
答案 2 :(得分:0)
尝试打开/dev/tty
。这将是您的进程的关联控制台,如果有的话。如果您的进程是从守护进程启动的,则可能会失败。