【问题标题】:Clearing the Console in C++在 C++ 中清除控制台
【发布时间】:2011-10-27 02:36:40
【问题描述】:

我正在尝试清除 C++ 中的控制台。我知道打印多个换行符是一种不好的做法,因为它可能会很慢,而且完全清除控制台窗口并不总是可靠的,但我研究了多个选项,除了system("cls") 之外几乎没有找到其他解决方案,这是一个更糟糕的选择。

基本上,我使用了cout << string(100, '\n'); 行,但是当我尝试运行该程序时遇到了一个几乎无法识别的错误。

error C2679: binary '<<' : no operator found which takes a right-hand operand of type 'std::basic_string<_Elem,_Traits,_Ax>' (or there is no acceptable conversion)

我也对此进行了研究,发现大多数解释对于我作为初级 C++ 程序员来说太复杂了,无法理解,或者与我的问题完全无关。

我的问题是 (1) 有没有办法修复这个错误,(2) 除了打印 100 个换行符之外,还有没有更好的跨平台清除控制台的方法?

我也听说过Console.clear(),但我不确定这是否是跨平台的。从我所见,它看起来更像是一个 Windows 命令。我也听说过 curses 库,我愿意研究和使用,直到我在某处读到不建议使用我熟悉的函数和 curses 库函数。

提前谢谢你!

【问题讨论】:

  • 请参阅此处:stackoverflow.com/questions/228617/… 以获得第二个问题的答案。
  • 清除屏幕是您想要的唯一非电传打字行为...或者您更普遍地想要诅咒行为(了解屏幕大小、定位光标、覆盖已写入的文本等) 。 ETC。)?如果是清除屏幕,我建议将其留给用户自己,因为在许多终端程序中都有击键。如果你无缘无故地在我的回滚缓冲区中写了一百个换行符......我个人会很生气!
  • @HostileFork 正如我所说,由于这些原因,我知道打印 100 个换行符是一种不好的做法。请问您知道哪些“击键”?
  • @NickLH 啊,是的,我也找到了那篇文章。不过,感谢您提供链接,以便我可以返回并再次查看!
  • @Abluescarab: ctrl-v 后跟 escape 再写 [2J 将清除屏幕

标签: c++


【解决方案1】:

关于你的错误......你必须......

#include <iostream> 
#include <string>

using namespace std;

如果您只使用 Windows,请使用 Windows 控制台 API。 如果您使用的是 linux\unix 终端,请使用转义码。 您可以执行 #if 在这两种方法之间进行选择。

在linux\unix上使用这样定义的write函数:

write(1,"\E[H\E[2J",7); // we use ANSI escape sequences here.

这里是解释如何做到这一点的微软页面。

http://support.microsoft.com/kb/99261

微软用于控制台的真正糟糕的控制台 api 总是让我生气 :) 为什么要使用 100 行代码来清除屏幕? :)

现在如果...你应该创建一个 clearscreen.h 文件和一个 clearscreen.cpp 文件。

在 clearscreen.h 我们只是把我们的函数。

 void clearconsole();

在 clearscreen.cpp 中,我们将代码用于两个操作系统

#ifdef _WIN32 || _WIN64

    #include <windows.h>

    void clearconsole()
    {
        ...
        // 100 lines of codes copied from microsoft article
    }

#else

    #include <unistd.h>

    void clearconsole()
    {
        write(1,"\E[H\E[2J",7);
    }

#endif

【讨论】:

  • 感谢您的回答!这是非常有价值的,尽管我一定要查一下 ANSI 转义码代表什么。在这一点上,我相信我正在使用许多特定于 Windows 的方法,所以无论如何我最终都可能使程序仅适用于 Windows。不过,如果不是太麻烦的话,我可以要求详细说明或链接如何使用#if 方法吗?再次感谢!编辑:啊,就是这样!谢谢!
  • 是的,我个人觉得这很乏味……如果世界上所有的操作系​​统都使用相同的方法,那就太好了,但我们都知道这不会发生。
  • 再次感谢您,因为我看到您不断更新您的答案以变得越来越具体! :D 我肯定会检查那个方法,并且很可能会采用它。
  • ncurses 对转义序列进行抽象化,使其可以在任何终端中工作。
  • 如果您在微软平台上,为什么不直接使用system("cls")。它完成了工作。
【解决方案2】:

猜测一下,您的直接问题是可能您缺少#include &lt;string&gt;

可能最便携的处理屏幕的方式是通过 ncurses。它包含在 POSIX 和大多数类似 POSIX 的系统中,也可作为大多数其他系统(例如 Windows)的库。

编辑:不管怎样,在 Windows 上清除屏幕不需要接近 100 行代码。

#include <windows.h>

void clear_screen(char fill = ' ') { 
    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, fill, cells, tl, &written);
    FillConsoleOutputAttribute(console, s.wAttributes, cells, tl, &written);
    SetConsoleCursorPosition(console, tl);
}

#ifdef TEST
int main(){ 
    clear_screen();
    return 0;
}
#endif

我是第一个说代码比我想要的更冗长的人——但它不到十行,更不用说一百行了。甚至 MS 知识库中的版本实际上也不足 40 行——其中很多是空白或 cmets。

然而,公平地说,我不得不承认直接写入硬件(或使用 BIOS)的汇编语言代码确实会缩短很多。

【讨论】:

  • 谢谢,该解决方案奏效了,尽管我知道这是一种不好的做法,而且我个人认为它看起来没有吸引力。我假设我应该同时包含 pcurses 和 ncurses 的 Windows 和 Linux 库,并使用下面提到的 #if 方法来检查操作系统是 Windows 还是 Linux?
  • @Abluescarab:我更喜欢使用#if作为一个规则。相反,我将特定于平台的代码分成几个特定的​​文件,并处理 makefile 中的差异。
  • 我对C++非常缺乏经验,我是一名高中生,刚加入C++班学习更多,所以我怕我对拆分的了解不多特定于平台的代码和处理生成文件中的差异。我不想打扰你解释它,除非你觉得有必要,因为它可能比我最初希望的要复杂一些。如果有一种简单、不复杂的方法来清除控制台,而不需要所有这些额外的废话,那就太好了。
  • @Abluescarab:一般 的想法很简单:为 Windows 提供一个文件。 Linux 的另一个文件。另一个适用于 MacOS。为每个操作系统构建时,只需在该操作系统的文件中编译。诅咒(例如)将处理该部分,因此您可以对任何(支持的)目标执行相同的工作。
  • 酷,我去看看!谢谢!
【解决方案3】:

我知道这是一个完整的死灵。但我发现我觉得这是一个相当巧妙的解决方案,并认为我会分享它以防万一将来有人遇到这个问题。

void clearConsole() {
#ifdef _WIN32
#include <iostream>
    static const char* CSI = "\33[";
    printf("%s%c%s%c", CSI, 'H', CSI, '2J');

#else
#include <unistd.h>
    write(1, "\E[H\E[2J", 7);
#endif
}

【讨论】:

    猜你喜欢
    • 2012-04-22
    • 2013-04-26
    • 1970-01-01
    • 2022-06-25
    • 1970-01-01
    • 1970-01-01
    • 2021-10-15
    • 1970-01-01
    相关资源
    最近更新 更多