IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 开发工具 -> 探究Visual Studio中的乱码问题 -> 正文阅读

[开发工具]探究Visual Studio中的乱码问题

关于乱码,没遇到皆大欢喜,遇到了头痛不已。在Visual Studio中程序遇到乱码,需要明确三个概念,那么问题就好解决了。

三个字符集概念

源码字符集

MSVC中/source-charset

源代码文本文件的字符集,NodePad++、记事本、VS Code这样类似的文本编辑器,可以打开源文件看一下你的字符集(文件编码)。

源代码文本文件是以二进制的形式存在硬盘里的,无论中文英文都一样,当你输入一个汉字后保存关闭,这个汉字就会按照你指定的字符集转换成二进制编码保存下去的,当你在以这个格式打开文件时候,就再按照你指定的字符集把二进制转回来。如果两次使用不同的字符集,也就会出现乱码了。

执行字符集

MSVC中 /execution-charset

在C++里 const char* str = "我";执行字符集决定了这行代码在编译器进行编译的时候,str存储的字节到底是什么,你可能会说源码字符集不是已经决定了这个”我”的二进制表示了么?没错,但是这个执行字符集就是让你在这里对它再解释一次。比如我源码字符集可能是UTF8的,但是我可以通过执行字符集来让最终str存储的是GBK的字节编码。

解析字符集

最终要还原显示这些二进制字节编码的时候,就需要用到它。比如通过printf()把前面的str显示到控制台时,这个printf()就会按照解析字符集来解析这些字节编码,找到指定字符显示出来。

Visual Studio中的字符集分析

默认情况下,Visual Studio 会检测字节顺序标记,以确定源文件是否采用编码的 Unicode 格式,例如 UTF-16 或 UTF-8。 如果未找到字节顺序标记,则假定源文件在当前代码页中编码,除非使用 /source-charset/utf-8 选项指定字符集名称或代码页。 Visual Studio 允许将 C++ 源代码保存在任意几个字符编码中。

代码页是一个字符集,可以包括数字、标点符号和其他标志符号。 不同的语言和区域设置可能使用不同的代码页。 例如,ANSI 代码页 1252 适用于英语和大多数欧洲语言;而 OEM 代码页 932 则适用于日本汉字。

上述为MIcrosoft的官方论述,有点绕。简而言之,对于执行字符集,Visual Studio默认根据系统的Locale来决定执行字符集,一般大家都是Windows中文系统,Locale是中国,那么就是GBK编码。对于解析字符集,如果没有手动更改的话,Visual Studio的标准输入输出(printf,cout)到命令行也是根据系统Locael决定的,也就是GBK。

如何使用UTF-8

为了全过程都能正常显示,不乱码,那应该三个阶段都需要设置为UTF-8。

源字符集和执行字符集设置为 UTF-8

可以使用 /utf-8 选项将源字符集和执行字符集指定为使用 UTF-8 编码的字符集。 它等效于在命令行上指定 /source-charset:utf-8 /execution-charset:utf-8

在 Visual Studio 开发环境中设置此编译器选项

  1. 打开项目“属性页” 对话框。 有关详细信息,请参阅在 Visual Studio 中设置 C++ 编译器和生成属性
  2. 选择“配置属性”>“C/C++”>“命令行”属性页。
  3. 在“附加选项”中,添加 /utf-8 选项以指定首选编码。
  4. 选择“确定”以保存更改 。

解析字符集设置为 UTF-8

SetConsoleCP 函数设置与调用进程关联的控制台所使用的输入代码页。 控制台使用其输入代码页将键盘输入转换为相应的字符值。

BOOL WINAPI SetConsoleCP(
  _In_ UINT wCodePageID
);

在mian()函数中加入以下代码

std::cout << "GetConsloeCP" << GetConsoleCP() << std::endl;
SetConsoleOutputCP(65001);//65001代表UTF-8,参见代码页标识符
std::cout << "GetConsloeCP" << GetConsoleOutputCP() << std::endl;

qDebug() << QTextCodec::codecForLocale()->name();
QTextCodec::setCodecForLocale(QTextCodec::codecForName("utf-8"));//Qt输出
qDebug() << QTextCodec::codecForLocale()->name();

另外,C++11可以指定字符串字面量的执行字符集了,const char* str = u8"我";在字符串前面加u8就可以了。

/source-charset(设置源字符集) | Microsoft Docs

/utf-8(将源字符集和执行字符集设置为 UTF-8) | Microsoft Docs

SetConsoleCP 函数 - Windows Console | Microsoft Docs

代码页 | Microsoft Docs

代码页标识符 - Win32 apps | Microsoft Docs

MSVC中C++ UTF8中文编码处理探究

  开发工具 最新文章
Postman接口测试之Mock快速入门
ASCII码空格替换查表_最全ASCII码对照表0-2
如何使用 ssh 建立 socks 代理
Typora配合PicGo阿里云图床配置
SoapUI、Jmeter、Postman三种接口测试工具的
github用相对路径显示图片_GitHub 中 readm
Windows编译g2o及其g2o viewer
解决jupyter notebook无法连接/ jupyter连接
Git恢复到之前版本
VScode常用快捷键
上一篇文章      下一篇文章      查看所有文章
加:2022-09-13 11:38:54  更:2022-09-13 11:42:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年12日历 -2024/12/28 19:00:55-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码
数据统计