如何清空控制台

126

如标题所述。如何在C++中清除控制台?


1
在哪个操作系统上?例如,在Linux和Windows上有很大的不同。如果你想在Windows上使用,请参考:https://dev59.com/uFbUa4cB1Zd3GeqPB8pn#5866648 - Jerry Coffin
你是想打印一堆行然后清除它,还是每行打印完就清除? - jpm
1
有时我想重置控制台视图。我不想用无数的换行符刷屏控制台。 - Thomas B
我在 C 语言中使用控制台窗口句柄询问“如何在不使用 system 的情况下清除 Win32 控制台窗口”。我收到的答案是这个。希望它能对你有所帮助。 - Agi Hammerthief
20个回答

82

对于纯C++

你不能这样做。C++甚至没有控制台的概念。

程序可以将输出打印到打印机,直接输出到文件,或被重定向到另一个程序的输入中。即使你可以在C++中清除控制台,它也会让这些情况变得更加混乱。

请参阅comp.lang.c++ FAQ中的这篇文章:

特定于操作系统

如果在您的程序中清除控制台仍然有意义,并且您想了解特定于操作系统的解决方案,那么这些解决方案确实存在。

对于Windows(如您的标签),请查看此链接:

编辑:之前提到使用system("cls");,因为Microsoft建议这样做。但是在评论中指出这是不安全的。由于这个问题,我已经删除了指向Microsoft文章的链接。

库(相对便携)

ncurses是一个支持控制台操作的库:


8
@Alf: 我是从微软文章中复制粘贴的,所以请给他们踩而不是我;) 不过我会修正它的。 - Merlyn Morgan-Graham
13
起源并不重要——不能通过g++编译的代码是不好的。但既然你修复了它,我取消了踩下去的投票。 :-) - Cheers and hth. - Alf
1
@YoushaAleayoub编辑了答案,删除了建议使用system的MS链接,并添加了指向您的文章解释原因的链接。 - Merlyn Morgan-Graham
对于那些寻找已删除链接的人:http://support.microsoft.com/kb/99261,尽管代码只是一个简单的调用`system(cls);`并包含了`cstdlib`头文件。请小心行事。 - Kröw

66

对于Windows,可以通过Console API实现:

void clear() {
    COORD topLeft  = { 0, 0 };
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    CONSOLE_SCREEN_BUFFER_INFO screen;
    DWORD written;

    GetConsoleScreenBufferInfo(console, &screen);
    FillConsoleOutputCharacterA(
        console, ' ', screen.dwSize.X * screen.dwSize.Y, topLeft, &written
    );
    FillConsoleOutputAttribute(
        console, FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_BLUE,
        screen.dwSize.X * screen.dwSize.Y, topLeft, &written
    );
    SetConsoleCursorPosition(console, topLeft);
}

它会快乐地忽略所有可能的错误,但是嘿,这是控制台清除。与system("cls")一样,并不意味着可以更好地处理错误。

对于*nix,通常可以使用ANSI转义代码,所以可以这样做:

void clear() {
    // CSI[2J clears screen, CSI[H moves the cursor to top-left corner
    std::cout << "\x1B[2J\x1B[H";
}

使用 system 这个方法太丑陋了。


9
使用系统来做这件事情真的很丑陋。- 为什么?我觉得看起来更简洁 :) - Merlyn Morgan-Graham
23
它会生成一个 shell 进程来清除控制台。这怎么能算是一种干净的解决方案呢?:P 这就像使用 system() 来通过 echo 输出而不是直接写入标准输出流。 - Cat Plus Plus
2
一行代码胜利!;) 是的,我是在开玩笑。它生成一个shell进程的事实对于你的答案来说是好信息。+1给*nix版本。 - Merlyn Morgan-Graham
8
使用system()是常见的错误。您提出的方法在Unix系统中也是如此。这是在POSIX系统上应该采取的方法。虽然您没有包含“滚动回溯”约定,但Win32部分是正确的。 - JdeBP
1
@JdeBP,你的链接已经失效了。这里有一个存档链接 - user2445507

43

对我来说,最简单的方法是不必重新发明轮子。

void Clear()
{
#if defined _WIN32
    system("cls");
    //clrscr(); // including header file : conio.h
#elif defined (__LINUX__) || defined(__gnu_linux__) || defined(__linux__)
    system("clear");
    //std::cout<< u8"\033[2J\033[1;1H"; //Using ANSI Escape Sequences 
#elif defined (__APPLE__)
    system("clear");
#endif
}
  • Windows 上,您可以使用 "conio.h" 头文件,并调用 clrscr 函数来避免使用 system 函数。
#include <conio.h>
clrscr();
  • Linux上,您可以使用ANSI转义序列来避免使用system函数。请查看此参考资料:ANSI Escape Sequences
    std::cout<< u8"\033[2J\033[1;1H"; 
  • MacOS上 调查中...

对我不起作用:打印“TERM环境变量未设置。” - secavfr

37

对于Linux/Unix以及可能一些其他系统,但不适用于Windows 10 TH2之前的版本:

printf("\033c");

将重置终端。


10

将多个行输出到窗口控制台是没有用的,它只会在其中添加空行。 不幸的是,这种方法是针对 Windows 系统特定的,并且涉及使用 conio.h(而 clrscr() 也可能不存在,该头文件也不是标准头文件)或 Win API 方法。

#include <windows.h>

void ClearScreen()
  {
  HANDLE                     hStdOut;
  CONSOLE_SCREEN_BUFFER_INFO csbi;
  DWORD                      count;
  DWORD                      cellCount;
  COORD                      homeCoords = { 0, 0 };

  hStdOut = GetStdHandle( STD_OUTPUT_HANDLE );
  if (hStdOut == INVALID_HANDLE_VALUE) return;

  /* Get the number of cells in the current buffer */
  if (!GetConsoleScreenBufferInfo( hStdOut, &csbi )) return;
  cellCount = csbi.dwSize.X *csbi.dwSize.Y;

  /* Fill the entire buffer with spaces */
  if (!FillConsoleOutputCharacter(
    hStdOut,
    (TCHAR) ' ',
    cellCount,
    homeCoords,
    &count
    )) return;

  /* Fill the entire buffer with the current colors and attributes */
  if (!FillConsoleOutputAttribute(
    hStdOut,
    csbi.wAttributes,
    cellCount,
    homeCoords,
    &count
    )) return;

  /* Move the cursor home */
  SetConsoleCursorPosition( hStdOut, homeCoords );
  }

对于POSIX系统而言,使用ncurses或终端函数会更加简单。
#include <unistd.h>
#include <term.h>

void ClearScreen()
  {
  if (!cur_term)
    {
    int result;
    setupterm( NULL, STDOUT_FILENO, &result );
    if (result <= 0) return;
    }

  putp( tigetstr( "clear" ) );
  }

5
// #define _WIN32_WINNT 0x0500     // windows >= 2000 
#include <windows.h> 
#include <iostream>

using namespace std; 

void pos(short C, short R)
{
    COORD xy ;
    xy.X = C ;
    xy.Y = R ;
    SetConsoleCursorPosition( 
    GetStdHandle(STD_OUTPUT_HANDLE), xy);
}
void cls( )
{
    pos(0,0);
    for(int j=0;j<100;j++)
    cout << string(100, ' ');
    pos(0,0);
} 

int main( void )
{
    // write somthing and wait 
    for(int j=0;j<100;j++)
    cout << string(10, 'a');
    cout << "\n\npress any key to cls... ";
    cin.get();

    // clean the screen
    cls();

    return 0;
}

4
清空屏幕,首先需要包含以下头文件:
#include <stdlib.h>

这将导入Windows命令。然后您可以使用“system”函数运行批处理命令(编辑控制台)。在C++中清除屏幕的命令为:

system("cls");
system("CLS");

这将清空控制台。整段代码如下:

#include <iostream>
#include <stdlib.h>

using namespace std;

int main()
{
system("CLS");
}

这就是你需要的全部内容!祝你好运 :)


3
system("cls") 不是一个可移植的解决方案,但它确实适用于 Windows 系统。 - CMS_95
5
那不是一个“模块”。C ++没有“模块”。此外,stdlib.h是由C标准指定的,并且与“导入Windows命令”或Windows本身无关。除了这些小问题,你的表现很好。 - Lightness Races in Orbit

3
在Windows中:
#include <cstdlib>

int main() { 
    std::system("cls");
    return 0;
}

在Linux/Unix中:

#include <cstdlib>

int main() { 
    std::system("clear");
    return 0;
}

3

由于MAC没有访问可帮助清除屏幕的windows功能,因此这对我来说很难做到。我的最佳解决方法是循环并添加行直到终端清除,然后运行程序。但是,如果您经常使用此功能,则这种方法不够高效或友好。

void clearScreen(){
    int clear = 5;
    do {
        cout << endl;
        clear -= 1;
    } while (clear !=0);
}

2
使用 system("cls") 来清屏:
#include <stdlib.h>

int main(void)
{
    system("cls");
    return 0;
}

2
已经在被接受的答案中提到了。这里没有新信息。 - Dialecticus
然后摆脱cout/wcout,只需将内容传输到system("echo " + 您的输出); - Tanveer Badar

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接