Displaying letters slowly on screen. Typing effect?

I saw how to display letters slowly in the archives and wanted to know how you would turn that code into a function so every cout will type slow

}
for( int i = 0; msg[i] != '\0'; i++ ) {
Sleep(200);
cout << msg[i]};
you can't force all couts to be slow with a function. you can call a function that prints slowly as above, but straight up calls to cout will still be normal pace.

there is probably another way to do this ... maybe a specialty stream override or something, or a custom friend string class or function with its own << operator that has the delays.

annoying but your own cout function is legal outside the std namespace, not recommended but it would replace the normal one...
Last edited on
Probably easiest: convert stuff to a string, then print each character after a short delay. Don't forget to flush the stream after each character.

Ideally you could inherit the most-derived type of the std::basic_streambuf which underlies std::cout, but that type is not public so that's not possible.

As an alternative you could keep a pointer to std::cout's associated stream buffer in a custom streambuf and forward arguments along to it, but that seems like a hack and I don't like it at all. According to Langer & Kreft all you'd need to do is implement overflow but I think that in 2023 a complete solution might need to do xsputn as well. Hack or not, here is a rough attempt:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
#include <chrono>
#include <thread>
#include <iostream>
#include <streambuf>

template <typename C,
          typename T = std::char_traits<C>>
  class my_basic_streambuf
    : public std::basic_streambuf<C, T>
  {
    using base_type = std::basic_streambuf<C, T>;
    base_type* managed_sb;

    my_basic_streambuf(std::basic_streambuf<C, T>* psb)
      : managed_sb(psb)
    {}

  public:
    template <typename C, typename T> friend class slow_stream;

  public:
    using
      typename base_type::traits_type,
      typename base_type::char_type,
      typename base_type::int_type,
      typename base_type::off_type,
      typename base_type::pos_type;

    int_type overflow(int_type c) override
    {
      auto const eof = traits_type::eof();
      if (!traits_type::eq_int_type(c, eof))
      {
        std::this_thread::sleep_for(std::chrono::milliseconds{ 100 });
        if (! traits_type::eq_int_type(managed_sb->sputc(c), eof))
        {
          managed_sb->pubsync();
          return c;
        }
        else return eof;
      }
      else return traits_type::not_eof(c);
    }
  };

template <typename C, typename T>
  class slow_stream
  {
    std::ostream& os; 
    my_basic_streambuf<C, T> new_sb;
    std::streambuf* old_sb;

  public:
    explicit slow_stream(std::basic_ostream<C, T>& os)
      : new_sb{ os.rdbuf() }, os{os}, old_sb{os.rdbuf(&new_sb)}
    {}

    slow_stream(slow_stream const&) = delete;
    slow_stream(slow_stream&&) noexcept = delete;
    slow_stream& operator=(slow_stream const&) = delete;
    slow_stream& operator=(slow_stream&&) noexcept = delete;
    ~slow_stream()
    {
      os.rdbuf(old_sb);
    }
  };

int main()
{
  {
    slow_stream ss{ std::cout };
    std::cout << "slow slow slow slow slow" << ' ' << 12345678 << '\n';
  }

  std::cout << "normal speed\n";

  {
    slow_stream ss{ std::cout };
    std::cout << "slow slow slow slow slow" << ' ' << 87654321 << '\n';
  }
}
Last edited on
thanks
this is really crude, but a short, low brow version (if you like the idea it needs to be cleaned up). A serious take probably would use a string view instead of pointers, but I have low energy lately.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#include <iostream>
#include<vector>
#include<cstdio>
#include<cstdlib>
#include <thread>         
#include <chrono>         
using namespace std;


class slostring
{	
    string * sp{};
	public:
	slostring(string &s){sp = &s;};
    friend ostream& operator<<(ostream& os, const slostring &str)
	{
		auto cp{str.sp->c_str()};
		int i{};
		while(cp && cp[i])
		{
			os << cp[i++];
			os.flush();
			std::this_thread::sleep_for (std::chrono::seconds(1));
		}
		return os;
	}	
};

int main() 
{
	string s{"the quick brown fox jumped over a lazy dog"};
	cout << slostring(s);
}


this is just like it used to come in over the phone line on a modem.
Last edited on
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#include <iostream>
#include <string>
#include <thread>
#include <chrono>

class slostring {
	const std::string& sp;

public:
	slostring(const std::string& s) : sp(s) {}

	friend std::ostream& operator<<(std::ostream& os, const slostring& str) {
		for (const auto& ch : str.sp) {
			os.flush() << ch;
			std::this_thread::sleep_for(std::chrono::milliseconds(200));
		}

		return os;
	}
};

int main() {
	const std::string s { "the quick brown fox jumped over a lazy dog" };

	std::cout << slostring(s) << '\n';
	std::cout << slostring("My very elderly mother jumped slowly up newbiggin parish") << '\n';
}


A bit more primitive:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

#include <time.h>
#include<string>
#include<iostream>

void update(int &s)
{
 time_t rawtime;
 time (&rawtime );
 s=rawtime;
}

std:: string slow(std::string s)
{
    int n,l;
    update(l);		
	for (int i =0;i<s.length();i++)
	{
		update(n);
		while (n==l ) update(l);
	std::cout<<s[i];	
	}
	return "";
}

int main()
{
	std::cout<<slow("Hello World!");
	std::cout<<std::endl<<"press enter to end . . .";
	std::cin.get();
}
Last edited on
Keeping things easier for you - a simple function ++

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <string>
#include <iostream>
#include <thread>
#include <chrono>

void printTextSlowly(std::string text, uint delay)
{
    for(char c: text)
    {
        std::this_thread::sleep_for(std::chrono::milliseconds(delay));
        std::cout << c << std::flush;
    }
}

int main()
{
    std::string myText = "Easy way to print slowly a text...";
    printTextSlowly(myText, 200);
    
    return 0;
}
Last edited on
Topic archived. No new replies allowed.