如何在Ubuntu系统中适配引用<windows.h>的C++控制台项目
Windows API 与 Ubuntu 等价实现对应
类Unix(含Ubuntu)系统的终端默认原生支持ANSI转义序列,你现有代码中clrLine等使用\x1B开头控制码的函数无需修改即可直接运行,仅需要调整依赖Windows API的初始化逻辑,你列出的9个Windows接口对应Ubuntu下的等价实现如下:
GetStdHandle:Ubuntu下标准输出默认对应文件描述符STDOUT_FILENO(定义于<unistd.h>),无需额外获取句柄STD_OUTPUT_HANDLE:等价于STDOUT_FILENO,常量值为1INVALID_HANDLE_VALUE:Linux系统调用出错默认返回-1,对应该错误标记CONSOLE_CURSOR_INFO:Linux无对应结构体,光标显隐直接通过ANSI转义序列控制:\x1B[?25l隐藏光标,\x1B[?25h显示光标SetConsoleCursorInfo/GetConsoleCursorInfo:普通场景无需对应实现,直接输出上述转义序列即可实现光标显隐控制,若需复杂光标状态查询可使用terminfo库能力GetConsoleMode/SetConsoleMode:等价于Linux下<termios.h>头文件中的tcgetattr()和tcsetattr()函数,用于修改终端属性ENABLE_VIRTUAL_TERMINAL_PROCESSING:Linux终端默认开启ANSI转义序列解析,无需额外配置该标记
跨平台适配修改方案
采用预编译宏区分平台,修改后代码可同时在Windows和Ubuntu下运行:
1. 头文件修改
#ifndef CONSOLE_OUTPUT_COMMON_H #define CONSOLE_OUTPUT_COMMON_H #include <string> #include <iostream> // 跨平台头文件区分 #ifdef _WIN32 #define _WINSOCKAPI_ #include <windows.h> #else // Linux依赖头文件 #include <unistd.h> #include <termios.h> #endif namespace ConsoleOutputCommon { void clrLine(); void moveCursorTopLeft(); void replaceLine(std::string s); void clrScreen(); void prepareConsole(); // 通用初始化接口,兼容原Windows接口 void prepareWindowsConsole(); // 保留原有接口名兼容旧调用 void clrRemainingScreen(); } #endif // !CONSOLE_OUTPUT_COMMON_H
2. 实现文件修改
#include "ms_windows_console_output_common_20200819.h" #include <cstdio> void ConsoleOutputCommon::clrLine() { printf("\x1B[2K"); } void ConsoleOutputCommon::moveCursorTopLeft() { printf("\x1B[1;1H"); } void ConsoleOutputCommon::replaceLine(std::string s) { printf("\x1B[2K"); std::cout << s; } void ConsoleOutputCommon::clrRemainingScreen() { printf("\x1B[J"); } void ConsoleOutputCommon::clrScreen() { printf("\033[2J"); } void ConsoleOutputCommon::prepareConsole() { #ifdef _WIN32 // Windows原有逻辑完全保留 DWORD error; HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE); if (hOut == INVALID_HANDLE_VALUE) { error = GetLastError(); } CONSOLE_CURSOR_INFO cursorInfo; GetConsoleCursorInfo(hOut, &cursorInfo); cursorInfo.bVisible = false; // hide the cursor SetConsoleCursorInfo(hOut, &cursorInfo); DWORD dwMode = 0; if (!GetConsoleMode(hOut, &dwMode)) { error = GetLastError(); } dwMode |= ENABLE_VIRTUAL_TERMINAL_PROCESSING; if (!SetConsoleMode(hOut, dwMode)) { error = GetLastError(); } #else // Linux初始化逻辑 // 隐藏光标 printf("\x1B[?25l"); // 若需要自定义终端输入输出模式,可在此处通过tcgetattr/tcsetattr修改 #endif ConsoleOutputCommon::clrScreen(); } void ConsoleOutputCommon::prepareWindowsConsole() { prepareConsole(); }
Ubuntu下编译运行说明
无需额外链接依赖库,直接使用g++编译即可:
g++ 你的实现文件名.cpp 其他项目文件.cpp -o 输出程序名
如果需要程序退出后恢复光标显示,可在初始化逻辑中添加退出钩子:
// 在prepareConsole的Linux分支中添加 atexit([](){ printf("\x1B[?25h"); });
内容的提问来源于stack exchange,提问作者Zeinab Rahmani
相关产品推荐
相关产品推荐

