从stdin反复读取EOF

时间:2013-11-03 04:56:47

标签: c++ io

我希望我的程序从stdin读取到EOF,打印所有输入,然后重复。我尝试按如下方式清除标准输入的EOF状态:

#include <string>
#include <iostream>
#include <iterator>

using namespace std;

int main() {

  cin >> noskipws;

  while (1) {

    printf("Begin");
    istream_iterator<char> iterator(cin);
    istream_iterator<char> end;
    string input(iterator, end);
    cout << input << endl;
    cin.clear();

  }

}

接收并打印第一个输入后,程序只是无限地打印“开始”而无需等待进一步输入。

2 个答案:

答案 0 :(得分:1)

你在那里采取的方法是行不通的 - 当'cin'在你正在使用的上下文中给你文件结尾时,cin就会关闭。

为了你所说的“阅读文本直到eof,然后再做一遍”,抱歉遗漏了之前的细微差别,但是如果你克隆stdin文件描述符然后使用克隆,您可以继续阅读这些附加文件描述符。

克隆iostream并不容易。见How to construct a c++ fstream from a POSIX file descriptor?

它有点类似于c,但是这段代码会耗尽stdin的一个副本,直到stdin关闭,然后它会创建一个新的副本并将其耗尽,然后开启。

#include <iostream>
#include <string>

void getInput(std::string& input)
{
    char buffer[4096];
    int newIn = dup(STDIN_FILENO);
    int result = EAGAIN;
    input = "";
    do {
        buffer[0] = 0;
        result = read(newIn, buffer, sizeof(buffer));
        if (result > 0)
            input += buffer;
    } while (result >= sizeof(buffer));
    close(newIn);

    return input;
}

int main(int argc, const char* argv[])
{
    std::string input;
    for (;;) {
        getInput(input);
        if (input.empty())
            break;
        std::cout << "8x --- start --- x8\n" << input.c_str() << "\n8x --- end --- x8\n\n";
    }
}

答案 1 :(得分:0)

那是因为你有printf(“开始”);在你的循环中,所以你每次循环都会再次打印它。

循环不会等待输入,因此每次从stdin读取数据时 - 如果没有任何内容,它会立即获得EOF,因此继续循环直到某些数据存在。

让我知道这是否有意义 - 或者我是否完全错了。

例如:

#include <string>
#include <iostream>
#include <iterator>

using namespace std;

int main() {

  cin >> noskipws;

  printf("Begin");

  while (1) {

    istream_iterator<char> iterator(cin);
    istream_iterator<char> end;
    string input(iterator, end);
    cout << input << endl;
    cin.clear();

  }

}