0

I'm writing a terminal application and I want to pause the program at certain points and wait for the user before continuing. I want to avoid OS dependent code so I'm not using Press any key to continue . . ., see this answer. I decided the next best thing is Press enter to continue . . ., but I can't seam to make that work reliably.

I've tried the following methods to pause for the user to input a newline character to no avail.

std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n')`;

std::string foo;
getline(std::cin, foo);

char foo{0};
std::cin >> std::noskipws;
while(foo != '\n') {
  std::cin >> foo;
}
std::cin >> std::skipws;

The problem is that I'm getting user input using std::basic_istream& operator>>(int) or std::basic_istream& operator>>(char) which leaves trailing whitespace. So if I receive input before calling my puaseForEnter() function then it doesn't pause, but if I call pauseForEnter() twice in a row, with some output in between, it works fine. Doubling up the code for pausing results in sometimes requiring the user to push enter twice.

I believe that detecting any other character would have the same issue.

I looked for a method to clear the stream (consume all characters currently in the stream) without causing it to pause, but I didn't see any. Is there another way to accomplish what I want?

Jacob Bischoff
  • 126
  • 1
  • 12
  • Why are you reading one character at a time if you only care about reading a whole line anyway? Just `getline` like you did before. – tadman Mar 18 '21 at 05:51
  • I'm only reading the whole line as a way to detect a newline character. I have several functions that get input as either a char or int and they don't care about getting the whole line, just the single value. – Jacob Bischoff Mar 18 '21 at 06:05
  • I'm saying that what you're doing, pulling in input and chucking it in the garbage until you get a newline, is *exactly* the same as a `getline`, except it's a lot more code and a lot of wasted effort. – tadman Mar 18 '21 at 06:06
  • Are you referring to the block of code? Those are just examples of what I've tried to get the behavior I want. You are correct that all three procedures have the same outcome. – Jacob Bischoff Mar 18 '21 at 06:10
  • Does this answer your question? [C++ wait for user input](https://stackoverflow.com/questions/21257544/c-wait-for-user-input) – tadman Mar 18 '21 at 06:11
  • No, that is the question with the answer that I referenced. The issue with `getchar`, or any other method I've explored, is that if the previous uses of `std::cin` didn't consume everything in the stream, than it wont pause. – Jacob Bischoff Mar 18 '21 at 06:17
  • Personally I'm not a fan of the "any key" thing, that died off in the 1980s. It's usually better to have a "Continue [y/n]:" type prompt, or something that's just a regular line input. If you need just one character you often have to drop down to OS-specific keyboard input calls, especially if you want it literally any key, including stuff like shift or alt. – tadman Mar 18 '21 at 06:19

1 Answers1

0

I decided to just check if the newline character was entered 'too quickly'. I don't like this solution because it can be unpridictable, but it will work most of the time.

void pauseForEnter() {
  std::cout << "Press Enter to continue ...";
  auto start{std::chrono::system_clock::now()};
  std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
  if (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now() - start).count() < 10) {
    std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n'); }
}
Jacob Bischoff
  • 126
  • 1
  • 12