Created
March 25, 2022 18:28
-
-
Save yduf/3806be006f79e31558b10026a85088da to your computer and use it in GitHub Desktop.
input logging stream
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// input logging | |
// inspired from https://en.cppreference.com/w/cpp/io/basic_streambuf/underflow | |
#include <iostream> | |
#include <sstream> | |
class buffer_logger : public std::streambuf { | |
std::streambuf* src; | |
char ch; // single-byte buffer | |
std::string input; | |
protected: | |
int underflow() { | |
traits_type::int_type i = src->sbumpc(); | |
if (traits_type::not_eof(i)) { | |
ch = traits_type::to_char_type(i); | |
setg(&ch, &ch, &ch+1); // make one read position available | |
// | |
input += ch; | |
if( ch == '\n') { | |
std::cerr << "=>" << input; | |
input = ""; | |
} | |
} | |
else { | |
std::cerr << "*>" << input << std::endl; | |
input = ""; | |
} | |
return i; | |
} | |
public: | |
buffer_logger(std::streambuf* buf) : src(buf) { | |
setg(&ch, &ch+1, &ch+1); // buffer is initially full | |
} | |
}; | |
class input_logger | |
{ | |
std::istream & in; | |
std::streambuf* const sbuf; | |
buffer_logger blog; | |
public: | |
input_logger(std::istream& in): | |
in( in), | |
sbuf(in.rdbuf()), | |
blog( sbuf) | |
{ | |
in.rdbuf(&blog); | |
} | |
~input_logger() { in.rdbuf(sbuf); } | |
}; | |
// Return content of stream as a string | |
// http://wordaligned.org/articles/cpp-streambufs | |
std::string load_stream(std::istream& src) | |
{ | |
std::ostringstream buf; | |
buf << src.rdbuf(); | |
return buf.str(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "input_logger.hh" | |
int main() { | |
// assume an input stream exist (work as well with cin) | |
char a[] = "This is the input\nhello\n"; | |
std::istringstream in(std::string(std::begin(a), std::end(a))); | |
// Then tie in stream to log stream, wich will output every input to cerr | |
input_logger log( in); | |
// use in stream normally | |
std::string first, second; | |
getline( in, first); // will log =>This is the input | |
in >> second; in.ignore(); // will log =>hello | |
// and it works as expected | |
std::cerr << "first is '" << first << "'\n"; | |
std::cerr << "second is '" << second << "'\n"; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment