只是作为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;
}
编辑以关注 cmets
经过一些测试,这(或多或少)是cls命令在cmd.exe中的实现方式(至少在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;
}
不是调用 api 函数来用所需的字符和属性填充缓冲区,而是滚动整个缓冲区,当滚动操作填充空白区域时,缓冲区被初始化。一站式 API 调用。
已编辑 这是 ansi 转义序列的“等效”代码。清除控制台但保留历史记录。这不会初始化完整的控制台缓冲区,仅确保控制台窗口是干净的,如果需要滚动可见窗口或缓冲区。
#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;
}