1

I have an array that will have thousands of elements. I have a for-loop to print it out, but only 200 at a time.

To continue with the next 200, the user gets the text "Press enter to continue" and i use cin.get(); to pause right there.

The printing get aweful with a lot of "Press Enter to continue" here and there so i thought of using carriage return to overwrite "Press Enter to Continue" with some "======".

Unfortunately my program is not overwriting it when I use cin.get(); first.

Is there a way around this?

string pressEnter = "\nPress Enter to continue . . .";
string lineBorders = "========================================================================================================";
    for (int *ia = arrayen, i = 1; ia < arrayenEnd; ia++, i++) 
    {
        cout << setw(10) << *ia;
        if (i > 9 && i % 10 == 0) {
            cout << endl;
        }
        if (i > 199 && i < size && i % 200 == 0) {
            cout << pressEnter << '\r' << flush;
            cout.flush();
            cin.get();

            cout << lineBorders << endl;

        }


    }
Newbie2018
  • 47
  • 8

1 Answers1

0

First of all, you shouldn't use std::cin.get(). If you type some characters and then press Enter, each character will cause one call to std::cin.get() to return. You could use std::getline(std::cin, string) instead to consume a whole line.

Secondly, the moment that your carriage return is printed, the cursor is already on a new line, since you pressed Enter. Additionally, a carriage return will not normally clear the line but only move the cursor. You can use CSI escape sequences [1] to achieve what you want: first move up one line \e[A, then clear the whole line \e[2K.

Putting it all together, you would get something like this:

#include <iostream>
#include <string>

int main() {
    while (true) {
        std::cout << "a\nb\nc\n";
        std::cout << "Press [Enter] to continue.";
        std::string line;
        std::getline(std::cin, line);
        std::cout << "\e[A\e[2K";
    }
}

On windows you must first enable parsing of escape sequences with SetConsoleMode() [2]. Judging from the docs it should look something like this (untested, I don't have windows):

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

int main() {
  // Get a handle to standard input.
  HANDLE handle = GetStdHandle(STD_INPUT_HANDLE);
  DWORD old_mode;
  bool escape_codes = false;

  // Get the old mode and enable escape code processing if everything works.
  if (handle != INVALID_HANDLE_VALUE) {
    if (GetConsoleMode(handle, &old_mode)) {
      DWORD new_mode = old_mode | ENABLE_VIRTUAL_TERMINAL_PROCESSING;
      escape_codes = SetConsoleMode(handle, new_mode);
    }
  }

  while (true) {
    // Same as other platforms.
    std::cout << "a\nb\nc\n";
    std::cout << "Press [Enter] to continue.";
    std::string line;
    std::getline(std::cin, line);

    // Only print escape codes if we managed to enable them.
    // Should result in a graceful fallback.
    if (escape_codes) {
      std::cout << "\e[A\e[2K";
    }
  }

  // Restore the old mode.
  if (escape_codes) {
    SetConsoleMode(handle, old_mode);
  }
}
Maarten
  • 106
  • 4
  • Thank you for your advice! I tried it out, but the print for a becomes: e[Ae[2Ka – Newbie2018 Jan 25 '18 at 20:59
  • That sounds like you're not using a terminal that understands CSI escape codes. Would you happen to be on windows? – Maarten Jan 25 '18 at 21:00
  • Actually, even windows terminals seem to support these escape codes: https://learn.microsoft.com/en-us/windows/console/console-virtual-terminal-sequences . Are you sure you added a backslash: `\e` ? – Maarten Jan 25 '18 at 21:02
  • I use VS on windows. Yes, I copy-pasted it on a new project just to try it out. – Newbie2018 Jan 25 '18 at 21:23
  • It would appear that on windows you must first call `SetConsoleMode(..., ENABLE_VIRTUAL_TERMINAL_PROCESSING)` before these escape codes are recognized: https://learn.microsoft.com/en-us/windows/console/setconsolemode – Maarten Jan 25 '18 at 21:33
  • Added an example for windows too. Can't test for windows though. – Maarten Jan 25 '18 at 21:47