【问题标题】:How do I clear the console in BOTH Windows and Linux using C++如何使用 C++ 在 Windows 和 Linux 中清除控制台
【发布时间】:2010-09-18 17:19:15
【问题描述】:

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

【问题讨论】:

  • 标准 C++11 中甚至不存在控制台,所以迂腐地你的问题甚至没有任何意义。那么你的程序foo 被重定向(例如foo > output.txt)或流水线(例如foo | grep xxx)呢?顺便说一句,有些计算机没有任何控制台(例如大多数 Web 服务器或 VPS)

标签: c++ windows linux console cross-platform


【解决方案1】:

我知道这不是在回答我自己的问题,但是! 这适用于 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);
}

【讨论】:

    【解决方案2】:

    简短的回答:你不能。

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

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

    【讨论】:

      【解决方案3】:

      这是您在任何其他平台上的操作方式,但在 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
      }
      

      【讨论】:

      • 这根本行不通。 \f 是换页符;它不会清除屏幕。
      【解决方案4】:

      clear the console on both platforms 没有通用命令。

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

      【讨论】:

      【解决方案5】:

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

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

      这就是 /usr/bin/clear 所做的,没有创建另一个进程的开销。

      【讨论】:

      • 要清楚:[H 将光标移动到屏幕的左上角 [2J 擦除屏幕任何想要了解更多细节的人都应该谷歌“ANSI 转义序列”。跨度>
      • 这仅适用于支持 ANSI 兼容转义序列的 Linux 终端。
      • 错误:没有匹配函数调用'write' write(1,"\E[H\E[2J",7); // 我们在这里使用 ANSI 转义序列。 ^~~~~ 我做了包含并检查了命名空间。
      【解决方案6】:

      发布的问题无法回答,因为它施加了不可能的限制。 “清除屏幕”在不同的操作系统中是一种非常不同的操作,而且它的操作方式操作系统而异。请参阅this Frequently Given Answer,了解如何在几个带有“控制台”的流行平台和带有“终端”的平台上执行此操作的完整说明。您还可以找到in the same place 对要避免的常见错误的一些解释,其中有几个是——唉! ——上面给出的答案。

      【讨论】:

        【解决方案7】:

        不会

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

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

        【讨论】:

          【解决方案8】:

          一个简单的技巧:为什么不使用宏结合使用 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);
          //....
          

          【讨论】:

            【解决方案9】:

            嗯,有一个非常接近的替代方法来清除屏幕。您可以尝试使用重复新行的 for 循环。例如:

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

            执行此循环后,终端不允许您滚动回顶部的位置,这是一种非常不专业的常识方法。它不会直接回答你的问题,但它可以工作。

            【讨论】:

            • @leonardo_assumpcao 10³³³³³³³³³³
            • 对于我 5.874 公里宽的显示器来说似乎足够了
            【解决方案10】:

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

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

            【讨论】:

            • 不是 c++ 标准的一部分,它只适用于 TurboC++
            • 但不是所有的编译器,只有少数。 LINUX上是否有任何conio.h,这是OP关心的? stackoverflow.com/questions/8792317/…
            • 在我编辑之前,您的代码甚至无法在 Windows/MSDOS 上编译
            • conio.h 在现代系统中是非常陈旧的 16 位编译器库,不推荐使用。
            【解决方案11】:

            简答

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

            长答案,请阅读:

            system("pause") clarification

            【讨论】:

              【解决方案12】:

              这段代码清除了 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__ */
              

              【讨论】:

                【解决方案13】:

                正如其他人已经说过的,在 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 << "\033[2J\033[1; 1H";
                #endif
                }
                

                您可以按照上面显示的模式,随意更改这两个代码段。

                【讨论】:

                  猜你喜欢
                  • 2013-04-26
                  • 1970-01-01
                  • 2012-04-22
                  • 1970-01-01
                  • 1970-01-01
                  • 2012-02-07
                  • 2012-02-18
                  • 1970-01-01
                  • 1970-01-01
                  相关资源
                  最近更新 更多