
mmocny wrote:
boost::iostreams::file log_file("sample.txt", std::ios::trunc); boost::iostreams::filtering_istream in; in.push( boost::iostreams::invert(boost::iostreams::tee(log_file)) ) /* this part is optional */ in.push( std::cin ); std::string s; int i; [snip] /* step 2 */ getline(in,s); /* note: filtering_istream wrapping std::cin passed here */ in >> i; std::cin.ignore( std::numeric_limitsstd::streamsize::max(), '\n' ); std::cout << s << std::endl << i << std::endl; [snip] The filtering_istream blocks on input, and will not resume until *4* EOF characters are sent. If I remove the invert(tee(log_file)) only *2* EOF need to be sent.
The problem comes from the buffering, which is in multiple places.
Neglecting the invert(tee(file)) for the moment, disabling buffering when push()-ing std::cin like this:
filtering_istream in;
in.push(std::cin, 0); //Note the "0 buffer size" passed here
causes the rest of your example program to function properly.
Buffering around the invert(tee(file)) can be made similarly:
in.push(invert(tee(log_file)), 0);
But this not enough, because of the way invert works: When reading from it, it first fills a buffer, and then flushes that buffer to the sink. What happens here is that not enough input can be read for filling the buffer, and this step thus blocks.
I'm not sure this is efficient, but setting a buffer size of 1 on the "invert" seems to work. (Annoyingly, the invert() function does not take a buffer size parameter, so I have to explicitely construct an inverse in what follows).
Summing up, constructing the filtering_istream as follows "works":
namespace bio = boost::iostreams;
bio::file log_file("deleteme.txt", std::ios::trunc);
bio::filtering_istream in;
in.push(bio::inverse