前进之路 发表于 2025-2-12 19:03:29

C++代码改造为UTF-8编码问题的总结

1. 引言

无论是哪个平台哪种编程语言,字符串乱码真是一个让人无语的问题:你说这个问题比较小吧,但是关键时刻来一下真是受不了。解决方式也有很多种,但是与其将编码转换来转换去,不如同一使用同一种编码方式,比如国际通用的UTF-8编码。因此,新的程序代码最好都同一使用UTF-8编码的方式。但是C++作为一种历史悠久的编程语言,肯定存在很多存量代码,如何将其改造成UTF-8编码也是一个问题,笔者在这里总结一二,可能不是很全,如果有遗漏就再开一篇补充。
2. 详述

2.1 操纵系统

同一使用同一使用UTF-8编码还有个好处是跨平台。但是操纵系统自己也是有字符编码的,这会影响到与操纵系统相干的应用,比如说终端。Linux系同一般不用担心,现在一般都默认使用UTF-8编码。Windows系统则有点麻烦,一般使用ANSI码(当地码)。当地码的意思就是基于当前系统地区设置的字符编码,以国内大陆的来说就是国标码:GB2312/GBK/GB18030。这就是为什么Windows的终端总是出现乱码的缘故原由,因为编码不一致:GBK编码的终端遇到UTF-8编码字符串当然不会正确展示了。
当然现在Windows系统也能设置成UTF-8编码了,如下图1所示。但是照旧发起不要轻易这么设置,Windows系统没有将UTF-8编码设置系统的默认编码主要也是为了保证兼容性,在Unicode编码大规模使用之前当地码照旧使用了相当长的时间的,有相当数据量的遗留程序都是使用的当地码。为了避免大规模应用程序乱码问题的出现,不能要求每个用户都这么设置。
https://img2024.cnblogs.com/blog/1000410/202502/1000410-20250212194117257-427979691.png
2.2 编译器

虽然最好不要在操纵系统层面设置成UTF-8编码,但是照旧可以编写基于UTF-8编码的程序的。将代码文件修改成UTF-8编码是一方面,另外一方面是编译器要将代码文件按照UTF-8编码进行编译。因为无论是ASCII、GB18030照旧UTF-8编码的文本文件,实在都是没有具体的标识符的,编译器需要知道以哪种字符编码来编译代码文件中的字符。
Linux系统照旧不用担心,默认情况下文本文件通常使用UTF-8编码,GCC编译器也会默认使用系统的默认字符编码也就是UTF-8编码来进行编译。麻烦的照旧Windows系统,暂时不讨论各种复杂的情况,笔者以Visual Studio的MSVC编译器为例,介绍一下自己的做法。
首先照旧要将代码文件修改成UTF-8编码,这里推荐使用Visual Studio的一个扩展:FileEncoding,它可以很方便的在代码页面的右下角修改代码文件编码,如下图2所示。不过有一点要注意,选择使用UTF-8编码而不是UTF-8(BOM)编码。
https://img2024.cnblogs.com/blog/1000410/202502/1000410-20250212194138044-1687284948.png
然后是给MSVC编译器增加一个编译选项:/utf-8,这个编译选项会将源代码字符集和执行字符集指定为使用UTF-8编码字符集。具体来说,如果你是原生的MSVC的项目,应该执行的操纵是:

[*]打开项目“属性页” 对话框。
[*]依次选择“配置属性”->“C/C++”->“命令行”属性页。
[*]在“附加选项”中,添加/utf-8选项以指定首选编码。
[*]选择“确定”以生存更改。
如果是CMake项目,那么在CMakeLists.txt中增加如下配置,意思是如果是MSVC编译器,就增加/utf-8选项:
# 判断编译器类型
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
    message(">> using Clang")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
    message(">> using GCC")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel")
    message(">> using Intel C++")
elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC")
    message(">> using Visual Studio C++")
    add_compile_options("/utf-8")
else()
    message(">> unknow compiler.")
endif()最后,还需要考虑一点,字符最终需要显示到终端的,无论是GUI终端照旧命令行终端,你必须确保终端的字符编码也是UTF-8编码才行。例如打印字符串到命令行终端,可使用如下示例代码(C++17情况下):
#include #ifdef _WIN32#include #endifusing namespace std;int main() {#ifdef _WIN32SetConsoleOutputCP(65001);#endifstring str = "这是中文字符串,测试能否正确显示!";std::cout
页: [1]
查看完整版本: C++代码改造为UTF-8编码问题的总结