How do I write to cin, the input stream, in C++ - c++

So I have a program (a game) designed to take input from a human via a keyboard. It is desirable, however, that at certain points I take control away from the user and make certain decisions for them. While it would be possible to write special-case code for use when events force the effects of user input to be emulated, I would much prefer to override the input stream (cin in this case) so that the program is in fact responding no different to forced decisions than had the user made such a decision of their own free will.
I have tried writing to it like I would an output stream (cin<<'z' for example) but the << operator isn't defined for cin and I don't know how to define it.
Would it be better to write to the keyboard buffer? If so, how would I do that in a system agnostic manner?

Writing to the input is quite a hack. It would be much cleaner design to put an abstraction layer between the actual input (like cin) and the game acting on that input. Then, you could just reconfigure this abstraction layer to respond to procedurally generated commands instead of to cin whenever necessary.

You can insert a streambuf into std::cin, something like:
class InjectedData : public std::streambuf
{
std::istream* myOwner;
std::streambuf* mySavedStreambuf;
std::string myData;
public:
InjectedData( std::istream& stream, std::string const& data )
: myOwner( &stream )
, mySavedStreambuf( stream.rdbuf() )
, myData( data )
{
setg( myData.data(), myData.data(), myData.data() + myData.size() );
}
~InjectedData()
{
myOwner->rdbuf(mySavedStreambuf);
}
int underflow() override
{
myOwner->rdbuf(mySavedStreambuf);
return mySavedStreambuf->sgetc();
}
};
(I've not tested this, so there may be errors. But the basic
principle should work.)
Constructing an instance of this with std::cin as argument
will return characters from data until the instance is
destructed, or all of the characters have been consumed.

I would believe that writing to cin is the symptom of a badly designed program.
You probably in fact want to have some event loop which of course is operating system specific. On Posix and Linux, you could build it above the poll(2) syscall, and you might want to set up a pipe(7) from your own process to itself.
Several libraries are providing some event loop: libevent, libev, and also frameworks like Qt, Gtk, POCO, libsdl ... (some of them are ported to several operating systems, so gives you an abstraction above the OS...)

Related

How to properly reroute output (away from std::cout)?

I have heard several times, that one should avoid plain writes to std::cout. (Is this correct?) However, I did not find good examples of how to achieve this. What I came up with so far is this:
#include <iostream>
class Logger {
std::ostream os;
auto RdBuffer( bool const decision ) { return decision ? std::cout.rdbuf() : nullptr; }
public:
explicit Logger( bool const use_cout = true ) : os( RdBuffer( use_cout ) ) {}
void Print() {
os << "Ptinting" << std::endl;
}
};
It allows me to write to std::cout if wanted, or stays silent otherwise. It seems to work, but I'm not sure this is the correct approach. What worries me in particular is the initialization with the nullptr and the consecutive writing to it in case the bool is set to false.
Is this going in the right direction? I'm particular interested in modern C++ ways of achieving this. So C++11 or newer answers are greatly appreciated.
Edit: Corrected typo in code.
I have heard several times, that one should avoid plain writes to std::cout. Is this correct?
No. It is accepted practice to write output to the standard output stream - unless you're in some embedded setting, or using an exotic OS where output is handled very differently.
The operating system and other processes will expect output to be written to that stream, or to whatever it represents (e.g. the standard output file handle on Unix-like systems).
What I came up with so far is this [piece of code here]
Well,
There are several popular logging libraries for C++. Here's a question about that over at SoftwareRecs.SX. No need to re-invenet the wheel if what you want is to do logging.
As #largest_prime_is_463035818 suggests in their comment, it's often good enough to just pass around an std::ostream and write to that. And when you want to not write anywhere - that's possible too; read these SO questions:
Standard no-op output stream
Printing to nowhere with ostream
Having said all this - there are some cases in which you might legitimately want to have std::cout itself be redirected to print somewhere else. I don't think that's covered by the standard, though.

What's the purpose of Boost pipe and why it's important?

Apologies if this question is overly broad. I'm new to C++ and trying to understand different stream types and why they matter (or doesn't matter).
I'm learning by coding a simple program that launch a child process, and process the output. I'm following the Boost process synchronous IO example: https://www.boost.org/doc/libs/1_75_0/doc/html/boost_process/tutorial.html#boost_process.tutorial.io.
One of the example can be reduce to this:
#include <boost/process.hpp>
using namespace std;
using namespace boost::process;
int main(int argc, char *argv[]) {
opstream in;
ipstream out;
child c("c++filt", std_out > out, std_in < in);
in << "_ZN5boost7process8tutorialE" << endl;
in.pipe().close(); // This will help c++filt quit, so we don't hang at wait() forever
c.wait();
return 0;
}
My question is:
Why do we have to use a boost opstream? Can I use istringstream instead (besides that it doesn't compile)? Can make it compile with istringstream?
Boost document said:
Boost.process provides the pipestream (ipstream, opstream, pstream) to wrap around the pipe and provide an implementation of the std::istream, std::ostream and std::iostream interface.
Does being a pipe matter, i.e. does pipe have significant implication here?
What Are Processes, How Do They Talk?
Programs interact with their environment in various ways. One set of channels are the standard input, output and error streams.
These are often tied to a terminal or files by a shell (cmd.exe, sh, bash etc).
Now if programs interact with eachother, like:
ls | rev
to list files and send the output to another program (rev, which reverses each line), this is implemented with pipes. Pipes are an operating system feature, not a boost idea. All major operating systems have them.
Fun fact: the | operator used in a most shells to indicate this type of output/input redirection between processes is called the PIPE symbol.
What Is A Pipe, Then?
Pipes are basically "magic" file-descriptors that refer to an "IO channel" rather than a file. Pipes have two ends: One party can writes to one end, the other party reads from the other.
Why?
Two reasons that come to mind right away
Files require disk IO and syncing, making it slow
Another fun fact: MSDOS has implemented pipes in terms of temporary files (on disk) for a very long time:
MS-DOS 2.0 introduced the ability to pipe the output of one program as the input of another. Since MS-DOS was a single-tasking operating system, this was simulated by redirecting the first program’s output to a temporary file and running it to completion, then running the second program with its input redirected from that temporary file. Now all of a sudden, MS-DOS needed a location to create temporary files! For whatever reason, the authors of MS-DOS chose to use the TEMP variable to control where these temporary files were created.
The pipe enables asynchronous IO. This can be important in case processes have two-way (full duplex) IO going on.
Okay Do I Care?
Yes, no, maybe.
You mostly don't. The ipstream/opstream classes are 100% compatible with std::istream/std::ostream, so if you had a function that expects them:
void simulate_input(std::ostream& os)
{
for (int i = 0; i < 10; ++i) {
os << "_ZN5boost7process8tutorialE" << std::endl;
}
}
You can perfectly use it in your sample:
bp::opstream in;
bp::ipstream out;
bp::child c("c++filt", bp::std_out > out, bp::std_in < in);
simulate_input(in);
in.close();
c.wait();
When You Definitely Need It
In full-duplex situations where you could easily induce a deadlock where both programs are waiting for input from the other end because they're doing the IO synchronously.
You can find examples + solution here:
How to reproduce deadlock hinted to by Boost process documentation?
boost::process::child will not exit after closing input stream
Boost::Process Pipe Streams and Unit Test

How can I derive my own stream from a standard stream?

How can I derive my own stream from a standard stream?
In C# language, there is a Stream class, but C++'s streams are too complex.
I want something like this:
class my_stream : public std::stream
{
// How to derive?
};
void using_a_stream(std::stream* s)
{
*s << "Hello world";
}
void main()
{
std::stream s1;
std::fstream s2("C:\\test.txt");
my_stream s3;
using_a_stream(&s1);
using_a_stream(&s2);
using_a_stream(&s3);
}
Note: The code just a sample and may be invalid C++ program.
Thanks.
I think there are three levels of answer to this question:
Level 1: It is complicated, especially if you are completely new to C++, stop right now. Only if you feel adventurous, continue to level 2.
Level 2: Use some library that makes creating streams easier. I would suggest using Boost.IOStreams library. It makes creating own streams and streambufs much easier. If you are still not satisfied, continue to level 3.
Level 3: You will have to derive from std::streambuf and modify its behaviour to suit your needs. Then you will have to plug your streambuf into own stream.
Could you please describe a little bit more what you own streamclass should do?
Just asking how without what is not the best way to get a constructive answer.
Maybe you should have a look at boost::iostream, as there is a much simpler and safer way to write own iostream classes.
Don't.
iostreams is an awful interface. It also lacks a lot of features and has awful performance.
Are the C formatted I/O functions (printf, sprintf, etc) more popular than IOStream, and if so, why?
What are the bad habits of C programmers starting to write C++?
Should I use printf in my C++ code?
Is it bad practice to use C features in C++?
Partially truncating a stream (fstream or ofstream) in C++

Internal "Tee" setup

I have inherited some really old VC6.0 code that I am upgrading to VS2008 for building a 64-bit app. One required feature that was implemented long, long ago is overriding std::cout so its output goes simultaneously to a console window and to a file. The implementation depended on the then-current VC98 library implementation of ostream and, of course, is now irretrievably broken with VS2008. It would be reasonable to accumulate all the output until program termination time and then dump it to a file. I got part of the way home by using freopen(), setvbuf(), and ios::sync_with_stdio(), but to my dismay, the internal library does not treat its buffer as a ring buffer; instead when it flushes to the output device it restarts at the beginning, so every flush wipes out all my accumulated output. Converting to a more standard logging function is not desirable, as there are over 1600 usages of "std::cout << " scattered throughout almost 60 files. I have considered overriding ostream's operator<< function, but I'm not sure if that will cover me, since there are global operator<< functions that can't be overridden. (Or can they?)
Any ideas on how to accomplish this?
You could write a custom stream buffer and attach it to cout with cout.rdbuf(). Your custom stream buffer would then tee the data to cout's original stream buffer and to a stream buffer stolen from an appropriate ofstream.
ofstream flog("log.txt");
teebuf tb(flog.rdbuf(), cout.rdbuf());
cout.rdbuf(&tb);
For your teeing stream buffer you can get an inspiration from this page.
You could use the pre-processor:
#define cout MyLogger
to inject new code.

Threadsafe logging

I want to implement a simple class for logging from multiple threads. The idea there is, that each object that wants to log stuff, receives an ostream-object that it can write messages to using the usual operators. The desired behaviour is, that the messages are added to the log when the stream is flushed. This way, messages will not get interrupted by messages from other threads. I want to avoid using a temporary stringstream to store the message, as that would make most messages at least twoliners. As I see it, the standard way of achieving this would be to implement my own streambuffer, but this seems very cumbersome and error-prone. Is there a simpler way to do this? If not, do you know a good article/howto/guide on custom streambufs?
Thanks in advance,
Space_C0wbo0y
UPDATE:
Since it seems to work I added my own answer.
Take a look at log4cpp; they have a multi-thread support. It may save your time.
So, I took a look at Boost.IOstreams and here's what I've come up with:
class TestSink : public boost::iostreams::sink {
public:
std::streamsize write( const char * s, std::streamsize n ) {
std::string message( s, n );
/* This would add a message to the log instead of cout.
The log implementation is threadsafe. */
std::cout << message << std::endl;
return n;
}
};
TestSink can be used to create a stream-buffer (see stream_buffer-template). Every thread will receive it's own instance of TestSink, but all TestSinks will write to the same log. TestSink is used as follows:
TestSink sink;
boost::iostreams::stream_buffer< TestSink > testbuf( sink, 50000 );
std::ostream out( &testbuf );
for ( int i = 0; i < 10000; i++ )
out << "test" << i;
out << std::endl;
The important fact here is, that TestSink.write is only called when the stream is flushed (std::endl or std::flush), or when the internal buffer of the stream_buffer instance is full (the default buffer size cannot hold 40000 chars, so I initalize it to 50000). In this program, TestSink.write is called exactly once (the output is too long to post here). This way I can write logmessage using normal formatted stream-IO without any temporary variables and be sure, that the message is posted to the log in one piece when I flush the stream.
I will leave the question open another day, in case there are different suggestions/problems I have not considered.
You think log4cpp is too heavy and you reach for Boost.IOStreams instead? Huh?
You may wish to consider logog. It's thread-safe for POSIX, Win32 and Win64.
Re. your own response. If you are using this for error logging and you program crashes before flushing your stream then you logging is a bit useless isn't it?