在Windows系统上,使用C语言是否可以清空命令行的输出?
例如,在Linux系统下,可以使用以下命令:
printf("\033[2J");
据我所知,Windows不认识ANSI转义码。谢谢。
编辑:我猜下一个输出前也需要将光标返回到0,0...
在Windows系统上,使用C语言是否可以清空命令行的输出?
例如,在Linux系统下,可以使用以下命令:
printf("\033[2J");
据我所知,Windows不认识ANSI转义码。谢谢。
编辑:我猜下一个输出前也需要将光标返回到0,0...
在Windows上有很多方法可以做到这一点。
您可以包含conio.h
并调用_clrscr();
或者您可以调用system("cls");
_clrscr();
或 clrscr();
- Rustamclrscr
在 C++Builder 中可用,但在 VC++ 中不可用(参见http://support.microsoft.com/kb/99261)。 - Eryk Sun作为替代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;
}
编辑遵循评论
经过一些测试,这大致是在 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;
}
不是通过调用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;
}
cls
命令采用不同的路线。它还获取屏幕缓冲区信息以获取缓冲区大小和填充字符属性。然后,它调用 ScrollConsoleScreenBuffer
将屏幕完全滚动到缓冲区之外,即滚动到目标 (0, 0 - dwSize.Y)
。一个更有用的命令(称其为 clear.exe)将使用 srWindow
中的窗口大小仅移动单个显示页面的缓冲区。这将在使用具有(许多)比窗口更多行的屏幕布局时保留输出历史记录。 - Eryk SunScrollConsoleScreenBuffer
的原因,抱歉,也许我错过了什么。无论如何,重新阅读问题和ansi转义的效果后,我认为你用clear.exe
方法是正确的。我手头没有C编译器进行测试,但等我有机会时,我会添加相应的代码。 - MC NDclear.exe
代码也已经包含在内。 - MC NDclear.exe
的作用类似于 Unix 终端中的 clear
或 ^J
。 - Eryk Sun