如何使用C++在Windows和Linux中清除控制台

How do I clear the console in BOTH Windows and Linux using C++

本文关键字:Linux 清除 控制台 Windows 何使用 C++      更新时间:2023-10-16

我需要一个用C++编写的跨平台解决方案来清除Linux和Windows中的控制台。这样做有什么作用吗?还要注意的是,我不希望最终用户程序员必须更改我的程序中的任何代码才能在Windows和Linux中清除(例如,如果必须在两个函数之间进行选择,则必须在运行时或编译时自主做出决定)。

在两个平台上都没有清除控制台的通用命令。

#include <cstdlib>
void clear_screen()
{
#ifdef WINDOWS
    std::system("cls");
#else
    // Assume POSIX
    std::system ("clear");
#endif
}

简单回答:你不能。

更长的答案:使用curses库(Unix上的ncurses,Windows上的pdcurses)。NCurses应该可以通过包管理器使用,并且NCurses和pdcurses都有完全相同的接口(pdcurses也可以独立于控制台创建类似控制台窗口的窗口)。

最难的答案是:使用#ifdef _WIN32和类似的东西,使您的代码在不同的操作系统上表现得不同。

在linux上,可以清除控制台。最好的方法是将以下转义序列写入stdout:

write(1,"E[HE[2J",7);

这就是/usr/bin/clear所做的,而不需要创建另一个进程的开销。

一个简单的技巧:为什么不通过使用宏和使用system()命令来清除控制台来检查操作系统类型?通过这种方式,您将使用适当的控制台命令作为参数来执行系统命令。

#ifdef _WIN32
#define CLEAR "cls"
#else //In any other OS
#define CLEAR "clear"
#endif
//And in the point you want to clear the screen:
//....
system(CLEAR);
//....

简短回答

void cls(void)
{
    system("cls||clear");
    return;
}

长答案,请阅读:

系统("暂停")澄清

发布的问题无法回答,因为它施加了不可能的限制。"清除屏幕"在不同的操作系统中是一种非常不同的操作,操作系统的具体操作方式也不同。有关如何在几个流行的带有"控制台"和带有"终端"的平台上进行操作的完整解释,请参阅此常见答案。你还会在同一个地方找到一些要避免的常见错误的解释,其中有几个是;唉—以上给出的答案。

在任何其他平台上都是这样做的,但在Windows:中不起作用

cout << "f";

也许您需要进行条件编译:

void clrscr()
{
#ifdef _WIN32
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coord = {0, 0};
    DWORD count;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hStdOut, &csbi);
    FillConsoleOutputCharacter(hStdOut, ' ',
                               csbi.dwSize.X * csbi.dwSize.Y,
                               coord, &count);
    SetConsoleCursorPosition(hStdOut, coord);
#else
    cout << "f";
#endif
}

我知道这不是在回答我自己的问题,但是!这适用于Windows(#include <windows.h>):

void clrscr()
{
    HANDLE hStdOut = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD coord = {0, 0};
    DWORD count;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hStdOut, &csbi);
    FillConsoleOutputCharacter(hStdOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &count);
    SetConsoleCursorPosition(hStdOut, coord);
}

除了清除屏幕,还有一个非常接近的选择。你可以试着使用一个for循环来重复很多新行。例如:

for (i = 0; i < 100000; i++)
{
  printf ("nnnnn");
}

在你完成这个循环后,终端不允许你滚动回顶部的位置,这是一种非常有常识的非专业方法。它不会直接回答你的问题,但它可以起作用。

这段代码清除了Windows和Unix中的控制台(尽管它实际上是以不同的方式编译的):

// File: clear_screen.h
#ifndef _CLEAR_SCREEN_H
#define _CLEAR_SCREEN_H
void clearScreen(void); /* Clears the screen */
#endif /* _CLEAR_SCREEN_H */
// File: clear_screen.c
#ifdef _WIN32
#include <windows.h>
void clearScreen(void) {
    HANDLE hOutput = GetStdHandle(STD_OUTPUT_HANDLE);
    COORD topLeft = {0, 0};
    DWORD dwCount, dwSize;
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    GetConsoleScreenBufferInfo(hOutput, &csbi);
    dwSize = csbi.dwSize.X * csbi.dwSize.Y;
    FillConsoleOutputCharacter(hOutput, 0x20, dwSize, topLeft, &dwCount);
    FillConsoleOutputAttribute(hOutput, 0x07, dwSize, topLeft, &dwCount);
    SetConsoleCursorPosition(hOutput, topLeft);
}
#endif /* _WIN32 */
#ifdef __unix__
#include <stdio.h>
void clearScreen(void) {
    printf("x1B[2J");
}
#endif /* __unix__ */

正如其他人已经说过的,在Windows和Linux上不可能有一段相同的代码来清除控制台。

我还强烈建议不要使用std::system:

  • 它使您的程序容易受到攻击;如果有人用自己的恶意程序替换clear/cls怎么办
  • 因此,反病毒程序讨厌std::system。如果你的代码使用它,即使它是无害的,产生的二进制文件也可能检测出病毒呈阳性。(请注意,它实际上是无害的。)

这是我的解决方案:

#ifdef _WIN32
#include <Windows.h>
#endif
void clrscr() {
#ifdef _WIN32
    COORD tl = { 0,0 };
    CONSOLE_SCREEN_BUFFER_INFO s;
    HANDLE console = GetStdHandle(STD_OUTPUT_HANDLE);
    GetConsoleScreenBufferInfo(console, &s);
    DWORD written, cells = s.dwSize.X * s.dwSize.Y;
    FillConsoleOutputCharacter(console, ' ', cells, tl, &written);
    FillConsoleOutputAttribute(console, s.wAttributes, cells, tl, &written);
    SetConsoleCursorPosition(console, tl);
#else
    std::cout << "33[2J33[1; 1H";
#endif
}

您可以按照上面显示的模式,并根据自己的喜好更改这两个代码段。

不会

for (int i=0;i<1000;i++){cout<<endl;}

清除所有操作系统中的屏幕?

如果您在控制台上工作,这应该可以工作

#include <conio.h>
int main()
{
    clrscr();
}