简体   繁体   English

反复从标准输入读到EOF

[英]Repeatedly reading to EOF from stdin

I would like my program to read from stdin until EOF, print all input, and repeat. 我希望程序从stdin读取到EOF,然后打印所有输入并重复。 I tried clearing the EOF state of stdin as follows: 我尝试清除stdin的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();

  }

}

After the first input is received and printed, however, the program just infinitely prints "Begin" without waiting for further input. 但是,在接收并打印了第一个输入后,程序将无限次打印“开始”,而无需等待进一步的输入。

The approach you're taking there won't work - when 'cin' gives you end-of-file in the context you're using, then cin is closed. 您所采用的方法行不通-当'cin'在您所使用的上下文中为您提供文件结尾时,cin被关闭。

For your stated purpose of "reading text until eof, then doing it again", sorry for missing the nuance of this previously, but if you clone the stdin file descriptor and then use the clone, you can continue reading from these additional file descriptors. 为了达到您所说的“读取文本直到eof,然后再做一次”的目的,对于以前错过的细微差别,我们深感抱歉,但是如果克隆stdin文件描述符然后使用克隆,则可以继续从这些其他文件描述符中进行读取。

Cloning iostreams isn't easy. 克隆iostream并不容易。 See How to construct a c++ fstream from a POSIX file descriptor? 请参阅如何从POSIX文件描述符构造c ++ fstream?

It's a little c-like, but this code will drain one copy of stdin until that stdin closes, then it'll make a new copy and drain that, and on. 它有点像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";
    }
}

That is because you have printf("begin"); 那是因为你有printf(“ begin”); inside your loop so you are going to get it printed again each time round the loop. 在循环中,这样您就可以在每次循环时再次打印它。

The loop will not wait for input so each time it reads data from stdin - if there is nothing there it immediately gets EOF and so continues looping until some data is present. 循环不会等待输入,因此每次它从stdin中读取数据时-如果没有任何内容,它将立即获得EOF,因此继续循环直到存在某些数据。

Let me know if this doesn't make sense - or if I got it totally wrong. 让我知道这是否没有道理-还是我完全理解错了。

eg: 例如:

#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();

  }

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM