1

I've been having an issue recently with std::cin where when I try to use it in conjunction with std::this_thread::sleep_for(), it starts to get an input when it hasn't even been called yet.

Here's the code I've been using:

#include <iostream>
#include <chrono>
#include <thread>
#include <string>

using std::string
using namespace std::this_thread
using namespace std::chrono

int main(){
    string a;
    sleep_for(seconds(3)); //start typing around now
    std::cin >> a;         //the text typed during the sleep_for() shows up now
    return 0;
}

When you start typing during the sleep_for(), the text just shows up afterwards when std::cin is called. I was wondering if anyone knew how to fix it and why it is happening.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
Paul T.
  • 31
  • 7

2 Answers2

2

The reason this shows up is that there are two components involved and they operate independently:

  • The second component is your program. All it typically does is its internal stuff and communication to the outside via stdin, stdout and stderr.
  • The first component is the console (terminal [emulator], commandline, DOS box .. there are various names for this) which actually displays output from your program and which receives input from the keyboard for your program.

The console works independently, that means that it gathers input for your program even if you program hasn't requested the input yet. This input is buffered and sent to your program, where you will receive it when you ask for it.

Now, what can you do about it? Firstly, you could write your own console which behaves as you would like it to, but that's far from trivial. Secondly, there are ways to communicate with the console via so-called escape sequences. These sequences e.g. allow you to display colours or bold fonts, but they are not standardized, so they depend on the console, so getting reliable results is also non-trivial. However, there are libraries for that like e.g. "curses" and various others with similar names. These even allow you to create text-based windows inside a console, and those should be the ones to look at.

Ulrich Eckhardt
  • 16,572
  • 3
  • 28
  • 55
  • Is there an equivalent to curses for Windows? After a very quick google search, I found that curse libraries are for Unix systems – Paul T. Dec 22 '15 at 11:51
  • Do a less quick search, e.g. https://stackoverflow.com/questions/138153/is-ncurses-available-for-windows popped up as one of the first results of mine. – Ulrich Eckhardt Dec 22 '15 at 12:17
0

In Linux you could do something like this:

...
std::cin >> a;         //the text typed during the sleep_for() shows up now
cout << "\e[A";. // move cursor up

for(size_t i=0; i<a.size(); i++){
    cout << "\b \b"; // erase one character
}

That's said, on Linux sleep_for doesn't stop typed text from showing immediately.

I'm not sure if there is windows equivalent for moving cursor up.

Amomum
  • 6,217
  • 8
  • 34
  • 62
  • Can you locate a link to explain those escape-sequences? Also, they depend on the console used and there are hundreds of them available. – Ulrich Eckhardt Dec 22 '15 at 09:18
  • @UlrichEckhardt, I got it from this question http://stackoverflow.com/questions/10058050/how-to-go-up-a-line-in-console-programs-c – Amomum Dec 22 '15 at 09:58