How to write cin, input stream, in C ++

So, I have a program (game) designed to enter information from a person using the keyboard. However, it is desirable that at certain points I take control of the user and make certain decisions for them. While it would be possible to write custom code to be used when events force emulate the effects of user input, I would rather override the input stream (cin in this case) so that the program does not actually respond to any other forced decisions than if the user made such a decision on own will.

I've tried writing to it as if I was an output stream (for example cin<<'z'

), but the <operator is not defined for cin and I don't know how to define it.

Would it be better to write a keyboard buffer? If so, how should I do this in an agnostic system?

+3


source to share


3 answers


The login entry is pretty hacked. It would be a much cleaner creation to place a layer of abstraction between the actual input (for example cin

) and the game acting on that input. Then you can simply reconfigure this abstraction layer to respond to the commands processed by the procedure, rather than cin

when necessary.



+8


source


You can embed streambuf in 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 haven't tested this, so there might be bugs. The principle should work.)

Constructing an instance of this using std::cin

as an argument will return characters from data

until the instance is destroyed or all characters have been destroyed.

+2


source


I believe that writing to cin

is a symptom of a poorly designed program.

You probably really want to have some kind of event loop , which of course depends on the operating system. On Posix and Linux, you can create it above polling (2) syscall, and you can configure pipe (7) from your own process to yourself.

Several libraries provide some kind of event loop: libevent , libev as well as frameworks like Qt , Gtk , POCO , libsdl ... (some of them are portable across multiple operating systems, so you get an abstraction over the OS ...)

0


source







All Articles