0

I was wondering if it is possible to simulate a typewriter effect (Meaning pause inbetween each character.) but from the cout global class.

For example

cout << "Hi, this is a cow." << endl;

would have the same effect has

typeWriter("Hi, this is a cow.\n");

Is it possible to change the global class of cout to something similar to the typeWriter function?

I know I could just change all the cout to typeWriter("xxx"), but that would take a long time (a couple hours of time).

cow9000
  • 39
  • 7
  • 3
    I see you wrote `cout` instead of `std::cout` - did you use `using namespace std;`? In this case that may actually be useful then, because you could write a custom object called `cout` that redirects to your `typeWriter`. – CompuChip Mar 24 '16 at 14:35
  • 1
    You can write a `struct` that overloads `operator <<` so you only need to replace `cout` by `type_writer`. You could even use a `#define` to do the replacing, but that is not good. – nwp Mar 24 '16 at 14:36
  • @Sergey A, Lol, assuming I only have about 30 minutes every day, and it took me about 10 hours to get this far. I think it is not laughable, go ahead and shame other people. – cow9000 Mar 24 '16 at 14:38
  • @CompuChip, This was just an example. Nothing that is actually in my program, just a question. – cow9000 Mar 24 '16 at 14:38
  • @nwp Thanks for your comment. :D – cow9000 Mar 24 '16 at 14:38
  • 1
    You should change your functions to take a `std::ostream&` and then use that instead of `std::cout`. Then you can write your own stream buffer to achieve the effect you want. This last bit isn't easy. – Simple Mar 24 '16 at 14:38
  • 4
    @cow9000, you probably didn't get what I said. *Large RPG games* usually take about a couple of hundreds of man-years to complete. – SergeyA Mar 24 '16 at 14:39
  • 2
    Sorry, thought that the code in your post was relevant to the question. Never mind then! – CompuChip Mar 24 '16 at 14:40
  • 3
    https://stackoverflow.com/questions/524641/how-do-i-create-my-own-ostream-streambuf – Simple Mar 24 '16 at 14:42
  • 2
    Re: "cout global class" -- I don't know about your cout, but `std::cout` is an **object**, not a class. – Pete Becker Mar 24 '16 at 14:51

1 Answers1

2

std::cout is not a class, but a static object. It is a std::ostream. You can change the behavior of an std::ostream by changing the underlying streambuffer. Derive your streambuffer from std::basic_streambuf<char>. It might use the old streambuff as base for the implementation and just add the slow down of the output:

class TypeWriterStreambuf: public std::basic_streambuf<char> {
    public:
        TypeWriterStreambuff(std::basic_streambuf<char>* base, 
                             std::chrono::milliseconds delay) : // ...
};

and then replace the one of std::cout like that:

using namespace std::chrono_literals;
auto b = new TypeWriterStreambuff{std::cout.rdbuf(), 100ms};
std::cout.rdbuf(b);

std::cout << "Hello World" << std::endl;

From now on the output should be written in that typewriter style.

cdonat
  • 2,748
  • 16
  • 24
  • Thanks! I will try this when I get home. Also thanks for the clarification – cow9000 Mar 24 '16 at 15:02
  • Good answer. How the hell is **100ms** valid C++? – SolaGratia Mar 24 '16 at 15:24
  • 1
    @BjarneStroustrup - with that Nick, you should know ;-) This is a user defined literal available in the standard library beginning with C++14: http://en.cppreference.com/w/cpp/chrono/operator%22%22ms – cdonat Mar 24 '16 at 15:31
  • @cdonat Haha it's more of an... ironic nickname lol. C++ never ceases to amaze me with its expressiveness. – SolaGratia Mar 24 '16 at 15:42