简体   繁体   中英

How do I delete a line text which has already been written on the terminal in c++?

I am currently making a Self Service Order Payment Program for a project and I was trying to figure out a way to erase the previous line of text to make it look cleaner. I discovered there was a similar function to system("CLS"); but instead of erasing all the text in the console, it only erases certain parts of the text.

I've been coding for about a week or two so if I missed anything please tell me.

switch(buy){

    case '1':
        //random code
        break;

     default:
            cout << "sorry thats not a valid number ;w;\n\n"; //remove this text after system("pause")
            system("pause");
            system("CLS"); //I need this to remove only one line instead of the whole thing.
        
            break;
}
    
        

The \n s at the end of this line makes it hard to remove the text on the line using only standard control characters:

cout << "sorry thats not a valid number ;w;\n\n"; 

Also, the system("pause"); is non-standard and will likely also result in a newline (I'm not sure about that).

What you could do is to skip the printing of \n and to just sleep a little before continuing.

Example:

#include <chrono>   // misc. clocks    
#include <iostream>
#include <string>
#include <thread>   // std::this_thread::sleep_for

// a function to print some text, sleep for awhile and then remove the text
void print_and_clear(const std::string& txt, std::chrono::nanoseconds sleep) {
    std::cout << txt << std::flush;      // print the text

    std::this_thread::sleep_for(sleep);  // sleep for awhile

    // Remove the text by returning to the beginning of the line and
    // print a number of space characters equal to the length of the
    // text and then return to the beginning of the line again.
    std::cout << '\r' << std::string(txt.size(), ' ') << '\r' << std::flush;
}

int main() {
    print_and_clear("sorry thats not a valid number...", std::chrono::seconds(1));
    std::cout << "Hello\n";
}

The above will print your text, sleep for a second, then remove the text and continue. What's left on the screen after the program has executed is only Hello .

you need to declare a variable and then use if condition.

i don`t know c++ but i give to hint here.

bool systempaused=false;

later on

if(!systempaused)
{

//print your line

}

system("pause")

You can do:-

cout<<"\r      lots of spaces                  "<<endl;

basically what \r escape sequence does is that it brings the cursor to the start of the line. If you print anything after printing \r it will overwrite what was already on that line

As I know there are no standard C++ only solutions for your task, there are platform-dependend ways that I'll describe below.

Main thing needed to achieve your task is to move cursor one line up. Afterwards you can just print spaces to clear line (and move cursor to start of line through \r ).

I provide two next variants ( Variant 1 and Variant 2 ) of solving your task.


Variant 1 . Using ANSI escape codes (Windows/Linux/MacOS).

There are so-called ANSI escaped codes that allow you to do rich manipulations of console. Including your task (moving cursor one line up).

Through this escape codes moving line up is achieved by printing string "\x1b[1A" to console (to move eg 23 lines up you may print "\x1b[23A" , see 23 inside this string). Also you may want to move cursor to right, this is achieved through "\x1b[23C" (to move 23 positions to right).

By default Linux/MacOS and other POSIX systems usually support ANSI escape codes (different terminal implementations may or may not support them). Windows also supports ANSI escape codes but they are not enabled by default, it needs to be enabled by special WinAPI functions.

Inside ClearLines() function don't forget to tweak width argument, it is set to 40 right now, it signifies width of your console, precisely it clears only first width chars of line with spaces.

Next code does what you need for Windows and Unix systems. Windows-specific code is located between #ifdef and #endif .

Try it online!

#include <iostream>
#include <cstdlib>

#ifdef _WIN32
#include <windows.h>
inline bool WinAnsiConsoleEnable(int stdout_or_stderr = 0) {
    if (!SetConsoleOutputCP(65001)) // Enable UTF-8 console if needed.
        return false;
    #ifndef ENABLE_VIRTUAL_TERMINAL_PROCESSING
        #define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004
    #endif
    DWORD outMode = 0;
    HANDLE stdoutHandle = GetStdHandle(stdout_or_stderr == 0 ?
        STD_OUTPUT_HANDLE : stdout_or_stderr == 1 ? STD_ERROR_HANDLE : 0);
    if (stdoutHandle == INVALID_HANDLE_VALUE)
        return false;
    if (!GetConsoleMode(stdoutHandle, &outMode))
        return false;
    // Enable ANSI escape codes
    outMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING;
    if (!SetConsoleMode(stdoutHandle, outMode))
        return false;
    return true;
}
#endif // _WIN32

static void ClearLines(size_t cnt, size_t width = 40) { // Clears cnt last lines.
    std::cout << "\r";
    for (size_t i = 0; i < cnt; ++i) {
        for (size_t j = 0; j < width; ++j)
            std::cout << " ";
        std::cout << "\r";
        if (i + 1 < cnt)
            std::cout << "\x1b[1A"; // Move cursor one line up, ANSI sequence.
    }
}

int main() {
    #ifdef _WIN32
        if (!WinAnsiConsoleEnable()) {
            std::cout << "Error enabling Win ansi console!" << std::endl;
            return -1;
        }
    #endif

    bool good = false;
    char buy = 0;
    std::cout << "Enter number:" << std::endl;
    while (!good) {
        std::cin >> buy;
        switch (buy) {
            case '1': {
                std::cout << "Valid number." << std::endl;
                good = true;
                break;
            }
            default: {
                std::cout << "Sorry thats not a valid number!\n";
                #ifdef _WIN32
                    std::system("pause");
                #else
                    std::system("read -p \"Press enter to continue . . . \" x");
                #endif
                ClearLines(4);
                break;
            }
        }
    }
}

Output (shown on Linux, Windows is same) (+ ascii-video ):

ASCII


Variant 2 . Using WinAPI functions (Windows-only).

Next variant works only for windows and uses only WinAPI console manipulation functions (no ANSI escapes).

#include <iostream>
#include <cstdlib>

#include <windows.h>

// Moves cursor by (DeltaX, DeltaY) = (offx, offy) relative to current position.
inline bool WinMoveCursor(int offx, int offy) {
    HANDLE hConsole = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO cbsi = {};
    if (!GetConsoleScreenBufferInfo(hConsole, &cbsi))
        return false;
    COORD coord = cbsi.dwCursorPosition;
    coord.X += offx;
    coord.Y += offy;
    if (!SetConsoleCursorPosition(hConsole, coord))
        return false;
    return true;
}

static void ClearLines(size_t cnt, size_t width = 40) { // Clears cnt last lines.
    std::cout << "\r";
    for (size_t i = 0; i < cnt; ++i) {
        for (size_t j = 0; j < width; ++j)
            std::cout << " ";
        std::cout << "\r";
        if (i + 1 < cnt)
            WinMoveCursor(0, -1); // Move cursor one line up, WinAPI.
    }
}

int main() {
    SetConsoleOutputCP(65001); // Enable UTF-8 if needed.

    bool good = false;
    char buy = 0;
    std::cout << "Enter number:" << std::endl;
    while (!good) {
        std::cin >> buy;
        switch (buy) {
            case '1': {
                std::cout << "Valid number." << std::endl;
                good = true;
                break;
            }
            default: {
                std::cout << "Sorry thats not a valid number!\n";
                std::system("pause");
                ClearLines(4);
                break;
            }
        }
    }
}

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