如何在C语言中清屏?

4

我希望能够清除屏幕上所有的文本内容。 我已经尝试使用:

#include <stdlib.h>
sys(clr);

提前致谢! 我使用的是OS X 10.6.8操作系统。抱歉有所混淆!


3
你使用的是哪个操作系统? - JSQuareD
重复的问题,请检查。 - Tarik
1
我相信这个问题的答案将取决于您使用的操作系统。您需要编辑问题并告诉我们您正在使用哪个操作系统。 - Paul Renton
1
请在找到答案时考虑这样做的智慧。许多用户,包括我在内,不喜欢程序随意清除屏幕或在我按下键但还没有确认输入是我想要的输入之前就去执行某些操作。除非您正在使用实际的TUI,否则这种行为从来不是必要的,通常只会令人感到烦恼。 - Crowman
那么,conio.h库的clrscr();函数在C语言中不能使用了吗?我用过很多次啊。 - Sid
显示剩余3条评论
4个回答

12

你需要查看curses.h。它是一个终端(光标)处理库,可以使所有支持的文本屏幕以类似的方式运行。

目前有三个发布版本,第三个版本(ncurses)是你需要的,因为它是最新的,并且已经移植到了最多的平台上。官方网站在此,还有一些好的教程。请点击这里阅读。

#include <curses.h>

int  main(void)
{
     initscr();
     clear();
     refresh();
     endwin();
}

5
为什么你要踩这个,curses 是一种实现这个的方式。 - tallen
5
不确定是谁给它投了反对票,但“curses”是其中一种方法,而不是唯一的方法。 - brianmearns
4
这可能算得上是一条评论,但它绝对不是一个答案,并且不太可能帮助到提问者。如果你能解释一下curses.h是什么以及为什么他应该查看curses.h,那可能会更好些。 - Sam I am says Reinstate Monica
1
因此,它是一个答案。 - tallen
2
我添加了更多信息,针对那些不想要通过谷歌搜索的人。 - Edwin Buck
显示剩余4条评论

7

清除屏幕最好的方法是通过调用stdlib.h中的system(const char *command)来调用shell:

system("clear"); //*nix

或者

system("cls"); //windows

再说一遍,尽量减少对调用系统/环境的函数的依赖,因为它们可能会导致各种未定义的行为。


5
真是浪费,你不需要为此分支出一个完整的进程,而且为什么要引入竞争条件呢? - Edwin Buck
因为提出了流程问题,为 Edwin 加一分。 - Jiminion
你会怎么做呢?在我看来,包含ncurses库有点过度了,而一个'clear'进程很少会拖慢大多数程序。 - Commander Worf
2
如果你认为添加一个库太过繁琐,那就试着运行一下程序。它会添加所有用于开发该程序的库。此外,由于该程序是一个“shell”,它会解释参数,在路径上查找程序,然后启动另一个程序。这一切只为了清除屏幕?ncurses是一个更好的选择,如果有人悄悄地插入了一个“clear”或“cls”的副本,或者有能力重新排列他们的路径,你就不会引入安全漏洞了。 - Edwin Buck
有人能够向我解释一下这里引入的竞态条件是什么,以及如何使用分叉来防止它吗? - gravitas
2
通过不运行两个程序来完成同一个任务,您可以避免这种情况。如果您决定采用此解决方案,则可以通过轮询操作系统以确保清除程序已干净退出,然后再将任何进一步的文本写入屏幕(这需要在程序中进行写锁定)来避免这种情况。这个“简单”的解决方案非常有问题,甚至很难修复。使用Jim记录的解决方案,它会让您多写五行代码,但不会出现这种竞争条件,因为所有屏幕逻辑都在一个进程中。 - Edwin Buck

3

Windows:

system("cls"); // missing 's' has been replaced

Unix:

system("clear");

您可以将此代码封装为单个、更便携的代码,如下所示:
void clearscr(void)
{
#ifdef _WIN32
    system("cls");
#elif defined(unix) || defined(__unix__) || defined(__unix) || (defined(__APPLE__) && defined(__MACH__))
    system("clear");
//add some other OSes here if needed
#else
    #error "OS not supported."
    //you can also throw an exception indicating the function can't be used
#endif
}

注意检查unix是非常广泛的。这也应该能够检测到您正在使用的OS X。


使用系统调用 => 需要额外的进程。嗯...... - Jiminion
@Jim 不错,但这是最简单直接的方法。在一个简单的控制台应用程序中,偶尔进行系统调用对性能几乎没有影响。 - JSQuareD
是的,我能看出这两种解决方案都有它们的用处。 - Jiminion
@JSQuareD,你说的头文件包含是正确的。抱歉,我在抱怨中想表达的部分是它假定了一个非常特定的环境配置,虽然是股票配置,但很容易在部署后进行修改。从这个意义上讲,除非您可以控制程序的整个生命周期内的执行环境,否则它不能保证功能。在我看来,这不值得麻烦,但你是对的,源代码是可移植的。 - Edwin Buck
@edwinbuck 嗯...我想吧。但我很难相信人们会取消定义这些宏或修改cls或clear的含义。而且如果他们这么做了,那么源代码也不是应该受到责备的。无论如何,我并不是说curses不是更便携/优雅的解决方案,我只是觉得如果你只想清空屏幕,那么使用它可能有点过头了。而且,将其实现到现有的控制台应用程序中可能需要一定的工作量。 - JSQuareD
显示剩余2条评论

1
这种函数的可用性,如clrscn()等类似函数,非常依赖于系统且不具备可移植性。
你可以保持简单并自己编写:
#include <stdio.h>

    void clearscr ( void )
    {
      for ( int i = 0; i < 50; i++ ) // 50 is arbitrary
        printf("\n");
    }

8
那不是C,而是C ++。它并没有清除屏幕,只是用空行填充了它。其中两个关键区别是光标最终停留在50个空行的底部(而不是在(0,0)处),并且可滚动缓冲区不会像清除屏幕时那样被擦除。 - brianmearns
4
对我来说,它编译成了C语言。它可用。大多数命令行程序不使用光标定位。 - David Elliman
这是您以前在VT终端上的操作方式! - tallen
1
这实际上是唯一真正可移植的解决方案。(但在您的TTY上可能会花费很多纸;-) - wildplasser
1
@DavidElliman:它编译为C,因为你改变了它=J。像你最初的cout <<那样的操作符重载在C中是不允许的。我关于它实际上没有清除屏幕的观点是,你的光标留在控制台底部而不是顶部。这不仅仅是光标寻址的问题,它是一个非常明显的外观差异。当你清除屏幕并开始输入时,你期望它出现在第一行,而不是最后一行。在大多数情况下,它可能在功能上是相同的,但对用户来说看起来和感觉都非常不同。 - brianmearns

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