简体   繁体   English

在Windows上使用C清除命令提示符

[英]Clear command prompt with C on windows

Is it possible to clear the output at the command prompt using C on windows? 是否可以使用Windows上的C在命令提示符下清除输出?

For example, on linux I could do 例如,在linux上我可以做到

printf("\033[2J");

But as far as I know windows doesn't recognise the ANSI escape codes Thanks. 但据我所知,Windows无法识别ANSI转义码谢谢。

EDIT: I guess I'll also need to get the cursor back to 0,0 fo r the next output after the clear... 编辑:我想我还需要在清除之后将光标恢复到下一个输出的0,0 ...

There are many way to do that on windows. 在Windows上有很多方法可以做到这一点。

You include conio.h and call _clrscr(); 你包括conio.h并调用_clrscr();

Or you can call system("cls"); 或者你可以打电话给system("cls");

Just as an alternative to the conio.h or the system call, just an implementation (i suposse that similar to the conio library) of how it is supossed to be done in windows. 就像conio.h或系统调用的替代方案一样,只是一个实现(我认为类似于conio库),它是如何在windows中完成的。

#include <windows.h>

int main(void){
    HANDLE hStdout; 
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
    DWORD dwCells, dwWritten;

    // Get console handle
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);     

    // Retrieve console information
    if (GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) {

        // Calc console cells
        dwCells = csbiInfo.dwSize.Y * csbiInfo.dwSize.X;

        // Initialize cursor position
        csbiInfo.dwCursorPosition.X = 0;
        csbiInfo.dwCursorPosition.Y = 0;

        // Replace all characters in console with spaces
        FillConsoleOutputCharacterA( hStdout, ' ', dwCells, csbiInfo.dwCursorPosition,  &dwWritten);
        // Replace all attributes in console with the default
        FillConsoleOutputAttribute( hStdout, csbiInfo.wAttributes, dwCells, csbiInfo.dwCursorPosition, &dwWritten );
        // Position the cursor
        SetConsoleCursorPosition( hStdout, csbiInfo.dwCursorPosition );
    }

    return 0;
}

edited to follow comments 编辑以关注评论

After some testing, this is (more or less) how the cls command is implemented in cmd.exe (at least in windows 7 64) 经过一些测试,这(或多或少)是如何在cmd.exe实现cls命令的(至少在windows 7 64中)

#include <windows.h>

int main(void){
    HANDLE hStdout; 
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
    COORD destinationPoint;
    SMALL_RECT sourceArea;
    CHAR_INFO Fill;

    // Get console handle
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);     

    // Retrieve console information
    if (GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) {
        // Select all the console buffer as source
        sourceArea.Top = 0;
        sourceArea.Left = 0;
        sourceArea.Bottom = csbiInfo.dwSize.Y - 1;
        sourceArea.Right = csbiInfo.dwSize.X - 1;

        // Select a place out of the console to move the buffer
        destinationPoint.X = 0;
        destinationPoint.Y = 0 - csbiInfo.dwSize.Y;

        // Configure fill character and attributes
        Fill.Char.AsciiChar = ' ';
        Fill.Attributes =  csbiInfo.wAttributes;

        // Move all the information out of the console buffer and init the buffer
        ScrollConsoleScreenBuffer( hStdout, &sourceArea, NULL, destinationPoint, &Fill);

        // Position the cursor
        destinationPoint.X = 0;
        destinationPoint.Y = 0;
        SetConsoleCursorPosition( hStdout, destinationPoint );
    }

    return 0;
}

Instead of call the api functions to fill the buffer with the required character and attribute, the full buffer is scrolled out and, as the scroll operation fills the empty area, the buffer get initialized. 不是调用api函数来填充具有所需字符和属性的缓冲区,而是滚动整个缓冲区,并且当滚动操作填充空区域时,缓冲区被初始化。 All in one api call. 一个api电话。

edited This is the "equivalent" code to the ansi escape sequence. 编辑这是ansi转义序列的“等效”代码。 Clear the console but keeping the history. 清除控制台但保留历史记录。 This does not initialize the full console buffer, only ensures the console window is clean, scrolling the visible window or the buffer if needed. 这不会初始化完整的控制台缓冲区,只能确保控制台窗口是干净的,滚动可见窗口或缓冲区(如果需要)。

#include <windows.h>

int main(void){
    HANDLE hStdout; 
    CONSOLE_SCREEN_BUFFER_INFO csbiInfo; 
    COORD destinationPoint;
    SMALL_RECT sourceArea;
    CHAR_INFO Fill;
    SHORT delta, end;

    // Get console handle
    hStdout = GetStdHandle(STD_OUTPUT_HANDLE);     

    // Retrieve console information
    if (GetConsoleScreenBufferInfo(hStdout, &csbiInfo)) {

        // How many lines needs the window to be moved to be clear
        delta = (csbiInfo.dwCursorPosition.Y) - csbiInfo.srWindow.Top;

        // Where the bottom of the window will fall after moving
        end = csbiInfo.srWindow.Bottom + delta;

        // If the window get out of the console buffer, it is necessary to scroll the buffer
        if (end >= csbiInfo.dwSize.Y){
            // Select all the console buffer as source
            sourceArea.Top = 0;
            sourceArea.Left = 0;
            sourceArea.Bottom = csbiInfo.dwSize.Y-1;
            sourceArea.Right = csbiInfo.dwSize.X-1;

            // Select the target point for the movement
            destinationPoint.X = 0;
            destinationPoint.Y = 0 - delta ;

            // Configure fill character and attributes for the empty area
            Fill.Char.AsciiChar = ' ';
            Fill.Attributes =  csbiInfo.wAttributes;

            // Scroll the buffer and init the end zone
            ScrollConsoleScreenBuffer( hStdout, &sourceArea, NULL, destinationPoint, &Fill);

            // Adjust new cursor position
            destinationPoint.X = 0;
            destinationPoint.Y = csbiInfo.dwSize.Y - (csbiInfo.srWindow.Bottom - csbiInfo.srWindow.Top + 1);

        } else {
            // No buffer scroll is needed. Adjust the new cursor position
            destinationPoint.X = 0;
            destinationPoint.Y = csbiInfo.dwCursorPosition.Y + 1;
        }

        // In any case, the visible window needs to be moved depending on the new cursor position
        sourceArea.Top = destinationPoint.Y;
        sourceArea.Left = destinationPoint.X;
        sourceArea.Bottom = destinationPoint.Y + (csbiInfo.srWindow.Bottom - csbiInfo.srWindow.Top + 1) -1 ;
        sourceArea.Right = csbiInfo.dwSize.X-1;

        // Place the visible window in the required place over the buffer
        SetConsoleWindowInfo(hStdout, TRUE, &sourceArea);

        // Place the cursor in its final position
        SetConsoleCursorPosition( hStdout, destinationPoint );
    }

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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