按下Ctrl+C终止程序后如何恢复终端正常显示与可见光标?
解决方案
问题原因
你按下Ctrl+C时系统会向程序发送SIGINT信号,默认处理逻辑是直接终止进程,不会执行你后续恢复光标显示的代码,终端就会保留光标隐藏的状态。
实现步骤
你可以通过注册信号处理函数+退出清理逻辑解决该问题,具体如下:
- 首先定义清理函数,用于恢复光标显示
- 通过
atexit()注册该清理函数,确保程序正常退出时也会执行 - 绑定
SIGINT(Ctrl+C触发)、SIGTERM等常见终止信号的处理函数,信号触发时正常退出即可自动触发清理逻辑
完整示例代码
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> // 仅示例中sleep函数需要,可按你实际需求调整 // 清理函数:恢复光标显示 void restore_cursor() { printf("\033[?25h"); fflush(stdout); // 确保输出立即生效,避免缓冲区残留 } // 信号处理函数 void signal_handler(int sig) { // 直接退出,会自动调用atexit注册的restore_cursor exit(EXIT_SUCCESS); } int main() { // 注册退出清理函数 atexit(restore_cursor); // 绑定信号处理逻辑 signal(SIGINT, signal_handler); // 处理Ctrl+C触发的终止 signal(SIGTERM, signal_handler); // 处理kill命令触发的终止 // 隐藏光标 printf("\033[?25l"); fflush(stdout); // 这里替换为你自己的数字时钟逻辑 while(1) { sleep(1); } return 0; }
补充说明
- 恢复光标的控制序列为
\033[?25h,和你隐藏光标用的\033[?25l是配对的ANSI转义序列,兼容绝大多数终端模拟器 - 调用
fflush(stdout)是为了避免转义序列滞留在输出缓冲区中不生效,建议每次输出控制序列后都加该语句 - 通过
atexit注册清理函数的好处是不用在每个退出路径都重复写恢复光标的代码,避免遗漏
内容的提问来源于stack exchange,提问作者Rasathurai Karan
相关产品推荐
相关产品推荐

