Files
yunNote/Languages/cpp/关于编码.txt

29 lines
2.1 KiB
Plaintext
Raw Permalink Normal View History

2026-03-14 10:40:58 +08:00
下面的讨论都是讨论Windows下的,因为其他平台基本都是默认U8,且支持OK。
测试情况如下:
// 编译选项:/std:c++17 /utf-8
int main() {
#if _WIN32 // 热知识:64 位 Windows 也会定义 _WIN32 宏,所以 _WIN32 可以用于检测是否是 Windows 系统
setlocale(LC_ALL, ".utf-8"); // 设置标准库调用系统 API 所用的编码,用于 fopen,ifstream 等函数
SetConsoleOutputCP(CP_UTF8); // 设置控制台输出编码,或者写 system("chcp 65001") 也行,这里 CP_UTF8 = 65001
SetConsoleCP(CP_UTF8); // 设置控制台输入编码,用于 std::cin
#elif __APPLE__
// 通常来说 MacOS 的默认编码就是 UTF-8,这里设置全局 locale 是为了让 iswspace 接受全角空格、iswpunct 接受全角逗号 L',' 等
setlocale(LC_ALL, "UTF-8"); // MacOS 设置 UTF-8 编码,让 iswspace 接受全角空格等
#elif __unix__
// 反正 Unix 系统默认都是 UTF-8,不设置也行,这里设置全局 locale 是为了让 iswspace 接受全角空格、iswpunct 接受全角逗号 L',' 等
//setlocale(LC_ALL, "zh_CN.utf-8"); // 设置使用中文本地化,可使 strerror 输出中文(但用户必须 locale-gen 过中文!)
setlocale(LC_ALL, "C.utf-8"); // 设置使用语言中性 locale(推荐),只影响 iswspace、iswpunct 等函数,不会使 strerror 等输出中文
#endif
// 这里开始写你的主程序吧!
// ...
std::cout << "你好,世界\n"; // 没问题!
std::ifstream fin("你好.txt"); // 没问题!
std::wcout << L"你好,世界\n"; // 你都统一 UTF-8 了,这破 UTF-16 和 UTF-32 之间来回跳的破 wchar_t 就别用了呗!
return 0;
}
这种方式其实基本就已经实现了全UTF-8的情况,但是有一个前提条件就是控制台支持UTF-8的读入,输出不清楚,
可能也有不少控制台支持输出U8,但支持UTF-8读入的好像不多,目前测试比较好的就是Windows Terminal。
不支持UTF-8输入的控制台,就只能用ReadConsoleW去自行封装解码,鉴于不够通用,没有深入研究。