c++io

Repeatedly reading to EOF from stdin


I would like my program to read from stdin until EOF, print all input, and repeat. I tried clearing the EOF state of stdin as follows:

#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.


Solution

  • 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.

    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.

    Cloning iostreams isn't easy. See How to construct a c++ fstream from a POSIX file descriptor?

    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.

    #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);
    }
    
    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";
        }
    }