system("cls") 在 Windows 上能用但不推荐,因其启动新进程调用 cmd.exe,导致性能开销大、受限环境易失败、存在命令注入安全风险;Linux/macOS 应使用 ANSI 转义序列 \033[2J\033[H 清屏并归位光标。

Windows 下用 system("cls") 能清屏,但跨平台不通用,且有安全与性能隐患;Linux/macOS 必须换方案。
为什么 system("cls") 在 Windows 上能用但不推荐
它依赖系统 shell 执行外部命令,本质是启动新进程调用 cmd.exe 的 cls 指令。这带来三个实际问题:
-
system()调用开销大,频繁清屏会导致明显卡顿 - 程序若以受限权限运行(如沙盒、CI 环境),
system()可能被禁用或直接失败 - 静态分析工具(如 Clang-Tidy)会标记它为“不安全函数”,因可能被注入恶意命令(比如字符串拼接了用户输入)
Linux/macOS 怎么等效清屏
类 Unix 系统没有 cls,但终端支持 ANSI 转义序列。最常用的是 \033[2J\033[H:
-
\033[2J:清空整个屏幕缓冲区 -
\033[H:将光标移到左上角(0,0)
直接输出即可:
std::cout << "3[2J3[H";注意:必须确保输出流未被重定向到文件(否则转义序列会原样写入),且终端支持 ANSI(现代终端基本都支持)。
立即学习“C++免费学习笔记(深入)”;
怎么写一个跨平台的清屏函数
不能靠宏简单判断 _WIN32 就调 system("cls")——Linux 下即使定义了该宏(比如 MinGW 交叉编译),system("cls") 依然会失败。稳妥做法是:
- 优先尝试 ANSI 序列(所有现代终端都支持,包括 Windows 10+ 的默认终端)
- ANSI 失败时(比如旧版 Windows 控制台未启用虚拟终端处理),再 fallback 到
system()
最小可用实现:
#ifdef _WIN32
#include
void clear_screen() {
HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFO csbi;
if (GetConsoleScreenBufferInfo(hOut, &csbi)) {
COORD coord = {0, 0};
DWORD written;
FillConsoleOutputCharacter(hOut, ' ', csbi.dwSize.X * csbi.dwSize.Y, coord, &written);
SetConsoleCursorPosition(hOut, coord);
} else {
std::cout << "\033[2J\033[H";
}
}
#else
void clear_screen() {
std::cout << "\033[2J\033[H";
}
#endif 注意:Windows 上用 FillConsoleOutputCharacter 比 system("cls") 更轻量、更可控。
容易被忽略的关键点
清屏不是“擦掉可见内容”那么简单:
- 滚动缓冲区(scrollback buffer)不会被 ANSI 序列或
FillConsoleOutputCharacter清除,用户仍可向上翻页看到历史输出 - 如果程序输出被重定向(如
./a.out > log.txt),任何清屏操作都无效,且 ANSI 序列会污染日志文件 - C++ 标准库不提供清屏抽象,所有方案都是平台/终端特定的——这意味着你写的“清屏”本质是和终端协议打交道,不是和 C++ 打交道










