Reputation: 384
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.
Upvotes: 0
Views: 1171
Reputation: 24259
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);
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";
}
}
Upvotes: 1
Reputation: 133
That is because you have 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.
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();
}
}
Upvotes: 0