简体   繁体   中英

C++ How do I erase a line from the console?

So I have this code that I'm working on and I used a switch statement. What I want to do is when any invalid option is selected, the program should display a message and then after some time clear only the message while keeping the options still on screen. In my so far of a code, I used Windows.h library's Sleep function for a pause and also used goto to go back to asking the option but can't seem to figure out how to erase the error message from the screen. I can't use system("cls"); because I have a menu before this option selection kind of like a login so I don't want it gone until a valid option has been selected. Here's my code:

cout<<endl<<"\t\t\t\t\t\t                            - Access Denied! -"<<endl;
cout<<"\t\t\t\t\t\t                         + Press [1] To Try Again. +"<<endl;
cout<<"\t\t\t\t\t\t                         + Press [2] To Go Back. +"<<endl;
char TryAgain = ' ';
cout<<"\t\t\t\t\t\t                                 >>[ ]<< ";
InvalidOption:
SetConsoleCursorPosition(hStdout, { 84, 14 });
cin>>TryAgain;
switch (TryAgain)
{
    case '1':
        goto LoginAgain;
    case '2':
        break;
    default:
        {
            cout<<"\t\t\t\t\t                            Select A Valid Option!";
            Sleep ( 450 );
            cout << "\b";
            goto InvalidOption;
        }
}

Yes I'm using tons of /t and maybe a bunch of other stuff but its just a sample code I was trying instead of directly experimenting on my original project.

If your terminal supports it, you can use ANSI escape codes ( here , here ), which provide more advanced console text control that allows you to remove multiple lines, print colored text, and skip all over the place.

The general format is ESC[X where ESC is the ASCII escape char ( 0x1b ), and X is the command. Many times X will be preceded by an integer argument, like in ESC[1A below, where 1 is the number of lines to move up.

Example:

#include <iostream>

// Erases `count` lines, including the current line
void eraseLines(int count) {
    if (count > 0) {
        std::cout << "\x1b[2K"; // Delete current line
        // i=1 because we included the first line
        for (int i = 1; i < count; i++) {
            std::cout
            << "\x1b[1A" // Move cursor up one
            << "\x1b[2K"; // Delete the entire line
        }
        std::cout << "\r"; // Resume the cursor at beginning of line
    }
}

int main() {
    std::cout << "\t\t\t\t\t\t         text" << std::endl;
    std::cout << "\t\t\t\t\t\t         more text" << std::endl;
    std::cout << "\t\t\t\t\t\t      even   more text \t\t" << std::endl;
    eraseLines(4);
    std::cout << "No one's here..." << std::endl;
}

Works on replit and with Cygwin Mintty

You might be able to use the carriage-return character \r . It usually goes together with line-feed \n , but its standalone function is "return the printing position to beginning of line". On some terminals, if you print that, you can print a bunch of spaces and overwrite your message.

cout << "\t\t\t\t\t Your stuff" << flush; // flush may be needed when you don't output \n
Sleep(450);
cout << "\r                          \r"; // return to start of line, print spaces, return again

All that provided you don't output a line-feed anywhere. If you do that, all is lost, you have to clear the whole screen.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM