宁远做网站,国外做网站的公司,html个人网站源码,百度指数分析平台功能描述#xff1a;最全的 Qt 字符编码相关知识以及中文乱码的原因与解决办法 一、字符编码种类
ASCII 码
美国人对信息交流的编码#xff0c;包括 26 个字母#xff08;大小写#xff09;、数字和标点符号等#xff0c;用一个字节#xff08;8 位#xff09;表示这些… 功能描述最全的 Qt 字符编码相关知识以及中文乱码的原因与解决办法 一、字符编码种类
ASCII 码
美国人对信息交流的编码包括 26 个字母大小写、数字和标点符号等用一个字节8 位表示这些字符实际只编到了第 127 个这就是 ASCII (American Standard Code for Information Interchange) 编码。
ASCII 扩展码
计算机传到其他国家发现有些本国的字符在 ASCII 码中没有就将这些字符编到 ASCII 剩余的位置128 到 255这就是 ASCII 扩展码。
gb2312
中文常用的汉字就 6000 多个中国人采用 gb2312 编码使用两个字节16 位有 65536 个编码位。前 127 个和 ASCII 一样后面的是汉字的编码。原先的 ASCII 就是半角符号后来新编的就是全角符号。“英文占一个字节汉字占两个字节”说的就是这套编码。
gbk
gb2312 生僻字 gbk
gb10830
gbk 少数民族文字 gb10830
Unicode
国际标准化组织制定出一套包含全世界所有语言文字的编码大家都用这套编码免得乱七八糟的谁也不认识谁这套编码就是 Unicode。
utf
Unicode 只是一套标准它只是规定了数字多少对应哪个字符但它不是计算机内部可用的具体实现就需要有给具体的方案将数字和字符的对照表输入到计算机内让机器也认识utf 就是 Unicode Transformation Format 的缩写意为 Unicode 转换格式。
utf24
Unicode 最长的编码需要 24 位用 3 个字节表示一个字符这个方案就被称为 utf24。这个想法好是好但是不符合实际情况。计算机一次读取的字节只能是 1、2、4、8 这样子不能一次读 3个字节所以 24 位的方案很快就被放弃了。
utf32
用 4 个字节表示一个字符这个方案就被称为 utf32。优点是简单明确不管是什么字符全都按 4 位读取简单明了。但缺点是浪费空间本来最多 3 个字节就够了但这每个字符至少浪费了一个字节。像英文这种一个字节就够最低位是具体内容其余 3 位都是 0直接有 3 位是浪费的也就是说一个 1GB 的英文文档需要 4GB 的存储空间生生的浪费的 3 倍。
utf16
有人提出用 16 位就够了那些一个字节的两个字节的字符直接用三个字节的通过某种算法可以使用两个字节来实现。使用 16 位来实现 Unicode 的码表这套方案就是 utf16。
utf8
utf8 是一个变长方案对于英文只要一个字节就行汉字则需要 3 个字节。 二、char * 和 QString 编码问题
char * 类型字符串是什么编码
对于程序内部声明的字符串char * 的编码取决于程序源文件的编码源文件是什么编码字符串就是什么编码。
对于程序外部传入的字符串比如从 argv 中读取的字符串其编码与源文件的编码无关只看当前操作系统的编码。
QString 是什么编码
Qt 的文档中明确指出QString 内部使用的是 Unicode 编码具体实现方案是 utf16。在使用char * 构造 QString 实例的时候QString 默认将 char * 当作是 utf8 编码去构造即QString s(char *) 等价于 QString s QString::fromUtf8(char*)。
同样是使用 char * 构造 QString为什么有的时候是乱码有的时候就不是乱码这取决于你的char * 是什么编码了如果是 utf8 的就不会有乱码问题如果是 gbk 的就会出现乱码的情况。 三、字符串长度
QString 字符串长度
只要 QString 能够正常构造没有乱码不管是英文还是中文都占一个长度。别忘了QString 用的是 utf16 方案一个长度占两个字节。
char * 字符串长度
char * 的长度需要看具体的编码了gbk 是英文一个长度汉字两个长度这里一个长度占一个字节。utf8 是英文一个长度汉字三个长度这里的一个长度也是一个字节。
所以不要太相信你的 strlen 函数关键是得看你是什么编码。 四、QTextCodec::setCodecForLocale 的真正含义
这个函数真正的作用只是告诉你的程序当前程序内部使用的字符编码是什么。这个函数无法对外部传入和内部声明的字符串产生影响和系统的编码或者源文件的编码无关。
经测试这个函数只对 QString 的 Local8bit 函数有影响。如果用这个函数将程序编码设置为 gbk那么 Local8bit 就是 gbk如果设置的编码是 utf8Local8bit 就是 utf8。用了这个函数解决了中文乱码问题一定是因为使用了 QString 的 toLocal8bit 或者 fromLocal8bit否则这个函数不会对中文乱码问题有任何影响。
假设你的系统是 gbk 的编码进程默认使用的编码也是 gbk这时候拿到一个 utf8 的 char *然后用 fromLocal8bit 来构造 QString这时候的 Local8bit 是 gbk但 char 是 utf8用 gbk 的规则去构造 utf8 的编码就乱码了。 五、char * 转 QString
utf8 的 char * 转 QString
如果 char *是 utf8 的QString 默认将 char * 当 utf8 处理用 QString s(char *) 或者 QString s QString::fromUtf8(char*) 直接构造就行了。
gbk 的 char * 转 QString
如果 char * 是 gbk 的需要先用 QTextCodec::setCodecForLocale 将 Local8bit 设置成 gbk再使用 fromLocal8bit 来构造。
QTextCodec::setCodecForLocale(QTextCodec::codecForName(GBK));
QString s QString::fromLocal8bit(char*);
不确定编码的 char * 转 QString
在实际编程的时候经常不确定这个 char * 是 utf8 的还是 gbk 的这时候可以用下面的方法进行构造。这段代码的含义是先将 char * 转成 utf8看是否成功不成功再转成 gbk。
char * c abcdefg;
QTextCodec::ConverterState state;
QString s QTextCodec::codecForName(UTF-8)-toUnicode(c, strlen(c), state);
if(state.invalidChars 0)
{s QTextCodec::codecForName( GBK )-toUnicode(c);
} 在 Qt5 中使用 QString::QStringLiteral 这个宏来处理中文乱码问题这个宏是官方提供专门处理乱码问题的。
tr() 不是处理中文乱码的这个函数是用来处理多语言问题的。 六、Windows 系统本地字符集编码
在 windows 命令行终端模式下输入命令chcp 如上图我的活动代码页为 936意思是“中国-简体中文 (GB2312)
下表列出了所有支持的代码页及其国家(地区)或者语言
代码页国家(地区)或语言437美国708阿拉伯文(ASMO 708)720阿拉伯文(DOS)850多语言(拉丁文 I)852中欧(DOS)-斯拉夫语(拉丁文 II)855西里尔文(俄语)857土耳其语860葡萄牙语861冰岛语862希伯来文(DOS)863加拿大-法语865日耳曼语866俄语-西里尔文(DOS)869现代希腊语874泰文(Windows)932日文(Shift-JIS)936中国-简体中文(GB2312)949韩文950繁体中文(Big5)1200Unicode1201Unicode (Big-Endian)1250中欧(Windows)1251西里尔文(Windows)1252西欧(Windows)1253希腊文(Windows)1254土耳其文(Windows)1255希伯来文(Windows)1256阿拉伯文(Windows)1257波罗的海文(Windows)1258越南文(Windows)20866西里尔文(KOI8-R)21866西里尔文(KOI8-U)28592中欧(ISO)28593拉丁文 3 (ISO)28594波罗的海文(ISO)28595西里尔文(ISO)28596阿拉伯文(ISO)28597希腊文(ISO)28598希伯来文(ISO-Visual)38598希伯来文(ISO-Logical)50000用户定义的50001自动选择50220日文(JIS)50221日文(JIS-允许一个字节的片假名)50222日文(JIS-允许一个字节的片假名-SO/SI)50225韩文(ISO)50932日文(自动选择)50949韩文(自动选择)51932日文(EUC)51949韩文(EUC)52936简体中文(HZ)65000Unicode (UTF-7)65001Unicode (UTF-8)
.cpp 或 .h 文件从 window 上传到 Ubuntu 后会显示乱码原因是因为 ubuntu 环境设置默认是 utf-8Windows 系统本地字符集默认编码为 GBK。
在简体中文 windows 系统下ANSI编码代表 GBK/GB2312 编码。 七、中文乱码现象
如果在 Qt Creator 中无法输入中文则选择“编辑”“Select Encoding…”“GBK…”或“UTF8BOM”点击“按编码重新载入”此时就可以输入中文了。
列举最常用的 3 个编译器微软 VC 的 cl 编译器MinGW 中的 gLinux 下的 g源代码分别采用 GBK 和无 BOM 的 UTF-8 以及有 BOM 的 UTF-8 这 3 种编码进行保存发生的现象如下表所示
★★★★★ 情况1指的是 Local 字符集为 GBK 情况2指的是 Local 字符集为 UTF-8 源代码的编码编译器显示正常显示乱码GBKwin vs cl情况1情况2win MinGW-g情况1情况2linux g情况1情况2UTF-8无 BOMwin vs cl 编译失败 error C2001常量中有换行符 编译失败 error C2001常量中有换行符 win MinGW-g情况2情况1linux g情况2情况1UTF-8有 BOMwin vs cl 情况1 情况2有 #pragma 预处理 情况2有 #pragma 预处理win MinGW-g情况2情况1linux g情况2情况1
源代码的编码“菜单” - “工具” - “选项” - “文本编辑器” - “行为” - “文件编码” - “默认编码”
常用的选项有以下几个
System 简体中文 windows 系统默认指的是 GBK 编码
GBK/windows-936-2000/CP936/MS936/windows-936
UTF-8
Local 字符集取决于 QTextCodec * codec QTextCodec::codecForName();
当使用 Visual C 编译程序的时候它会分析源文件采用何种编码有 BOM 标识符则可以正确识别其编码是 UTF-8若没有 BOM 标识符则认为其使用本地字符集编码Local 字符集。
如果源文件是 UTF-8BOM 的编码方式还需要在头文件加入
#if defined(_MSC_VER) (_MSC_VER 1600)
#pragma execution_character_set(utf-8)
#endif
或者在 .pro 文件中添加
QMAKE_CXXFLAGS /utf-8
如果源文件是 UTF-8无 BOM 的编码方式则一定不能加 #pragma execution_character_set(“utf-8”)不然会产生乱码。
当 QTextCodec::codecForName(utf-8) 时
QString::fromLocal8Bit 和 QString::fromUtf8 是等效的。
当 QTextCodec::codecForName(gbk) 时
QString::fromLocal8Bit 和 QString::fromUtf8 是不等效的。
★★★★★
如果该工程不需要跨平台使用只在 Win那么工程设置请使用 GBK 的编码方式
如果该工程要跨平台使用WinLinux那么工程设置请使用 UTF-8BOM 的编码方式Local 字符集设置为 UTF-8。
UTF-8 和 GBK 其实对英文和数字都是一样的 ASCII 单字节编码所以源文件用英文和数字是肯定不乱码主要是汉字之类的本地语言文字编码显示容易出错。
Windows 系统里一般的记事本、编辑器、VC 开发环境等都是默认用 GBK 汉字编码而 Linux 和 Qt 都是默认用 UTF-8 国际文字编码所以文本显示乱码一般都是这个原因。 八、“UTF-8 无 BOM 格式”和 “UTF-8 带 BOM 格式”的区别
BOM—Byte Order Mark就是字节序标记。
UTF-8 带 BOM 格式就是在文件头添加了 3 个 bits 的 b\xef\xbb\xbf字符。
通常编程特别是 Linux 下编程建议使用 “UTF-8 无 BOM 格式”这种不含 BOM 的 UTF-8 才是标准形式由于含有 BOM 的 UTF-8 常常和 Linux 系统经常使用的 # 冲突。
若是在 windows 下编程建议使用 “UTF-8 带 BOM 格式”这样比较好。
如今只有微软还在坚持使用带 BOM 格式的 UTF-8由于它便于较快的与不少本地编码如 gbkascii 相区分。总之微软为了向前兼容性一直坚持使用带 BOM 格式的 UTF-8。 九、查看 Qt Creator 源文件的编码格式
点击菜单 “工具” - “选项” - “文本编辑器”右边选择“显示”看到下图 选中 “Display file encoding”然后点击 “OK” 按钮就可以在编辑器右上角看到当前文件的编码格式 十、解决中文乱码的方法
总结下解决中文乱码的方法
其中源代码的编码“菜单” - “工具” - “选项” - “文本编辑器” - “行为” - “文件编码” - “默认编码”Local字符集取决于QTextCodec *codec QTextCodec::codecForName();
必须保证源文件的编码和显示文字的编码保持一致否则中文乱码。
放了方便起见通常将源文件的编码和显示文字的编码设置保持一致。
如果没有设置 Local 字符集则使用默认系统的字符编码方式windows 下是 GBK 编码Linux 下是 UTF-8 编码。
直接输入文字QString 默认将 char * 当作是 UTF-8 编码去构造。
情况1如果是msvc 2013/2015/2017等编译器
(1) 源文件编码设置为 GBK
Local字符集设置为 GBK
采用 QString::fromLocal8Bit() 对中文进行转码则显示正常否则乱码因为设置了本地字符集为 GBK 编码fromLocal8Bit() 就是将中文转换为 GBK 编码。
没有设置 Local 字符集
如果没有设置 Local 字符集编码方式则 Qt 采用默认的系统字符编码方式 GBK和上述 “Local字符集设置为GBK” 转码方法相同。
Local 字符集设置为其它编码方式如 UTF-8
中文显示乱码因为无法将显示文字的编码方式设为 GBK。
(2) 源文件编码设置为 UTF-8无 BOM
大概率报错编译失败error C2001: 常量中有换行符
有时候能显示出来如果没报错
Local 字符集设置为 UTF-8
直接输入中文QString 默认将 char * 当作是 UTF-8 编码去构造、采用 QString::fromLocal8Bit()此时本地字符集为 UTF-8、采用 QString::fromUtf8() 都能显示正常。
没有设置 Local 字符集
如果没有设置 Local 字符集编码方式则 Qt 采用默认的系统字符编码方式 GBKQString::fromLocal8Bit()此时本地字符集为 GBK则显示乱码直接输入、采用QString::fromUtf8() 都能显示正常。
Local 字符集设置为其它编码方式如 GBK
和上述“没有设置 Local 字符集”相同QString::fromLocal8Bit()此时本地字符集为 GBK则显示乱码直接输入、采用 QString::fromUtf8() 都能显示正常。
(3) 源文件编码设置为 UTF-8有 BOM
Local 字符集设置为 UTF-8
需要先进行以下设置
在 main 函数头文件下面添加以下语句
#if defined(_MSC_VER) (_MSC_VER 1600)
#pragma execution_character_set(utf-8)
#endif
或者在 .pro 文件中添加
QMAKE_CXXFLAGS /utf-8
设置完成后直接输入中文QString 默认将 char * 当作是 UTF-8 编码去构造、采用QString::fromLocal8Bit()此时本地字符集为 UTF-8、采用 QString::fromUtf8() 都能显示正常。
没有设置Local字符集
直接输入、采用 QString::fromUtf8() 都显示乱码QString::fromLocal8Bit()显示正常。
如果进行以下设置则直接输入、采用 QString::fromUtf8() 都显示正常而 QString::fromLocal8Bit() 显示乱码。
在 main 函数头文件下面添加以下语句
#if defined(_MSC_VER) (_MSC_VER 1600)
#pragma execution_character_set(utf-8)
#endif
或者在 .pro 文件中添加
QMAKE_CXXFLAGS /utf-8
Local 字符集设置为其它编码方式如 GBK
和上述“没有设置 Local 字符集”相同直接输入、采用 QString::fromUtf8() 都显示乱码QString::fromLocal8Bit() 显示正常。
如果进行以下设置则直接输入、采用 QString::fromUtf8() 都显示正常而 QString::fromLocal8Bit() 显示乱码。
在 main 函数头文件下面添加以下语句
#if defined(_MSC_VER) (_MSC_VER 1600)
#pragma execution_character_set(utf-8)
#endif
或者在 .pro 文件中添加
QMAKE_CXXFLAGS /utf-8 情况2如果是MinGW编译器
(1) 源文件编码设置为 GBK
Local 字符集设置为 GBK
采用 QString::fromLocal8Bit() 对中文进行转码则显示正常否则乱码因为设置了本地字符集为 GBK 编码fromLocal8Bit() 就是将中文转换为 GBK 编码。
没有设置 Local 字符集
如果没有设置 Local 字符集编码方式则 Qt 采用默认的系统字符编码方式 GBK和上述 “Local 字符集设置为 GBK” 转码方法相同。
Local 字符集设置为其它编码方式如 UTF-8
中文显示乱码因为无法将显示文字的编码方式设为 GBK。
(2) 源文件编码设置为 UTF-8无 BOM
Local 字符集设置为 UTF-8
直接输入中文QString 默认将 char * 当作是 UTF-8 编码去构造、采用 QString::fromLocal8Bit()此时本地字符集为 UTF-8、采用 QString::fromUtf8() 都能显示正常。
没有设置 Local 字符集
如果没有设置 Local 字符集编码方式则 Qt 采用默认的系统字符编码方式 GBKQString::fromLocal8Bit()此时本地字符集为 GBK则显示乱码直接输入、采用 QString::fromUtf8() 都能显示正常。
Local 字符集设置为其它编码方式如 GBK
和上述“没有设置 Local 字符集”相同QString::fromLocal8Bit()此时本地字符集为 GBK则显示乱码直接输入、采用 QString::fromUtf8() 都能显示正常。
(3) 源文件编码设置为 UTF-8有 BOM
UTF-8 有 BOM和无 BOM 对 MinGW 编译器没有影响。
Local 字符集设置为 UTF-8
直接输入中文QString 默认将 char * 当作是 UTF-8 编码去构造、采用 QString::fromLocal8Bit()此时本地字符集为 UTF-8、采用 QString::fromUtf8() 都能显示正常。
没有设置 Local 字符集
如果没有设置 Local 字符集编码方式则 Qt 采用默认的系统字符编码方式 GBKQString::fromLocal8Bit()此时本地字符集为 GBK则显示乱码直接输入等价于 QString::fromUtf8()、采用 QString::fromUtf8() 都能显示正常。
Local 字符集设置为其它编码方式如 GBK
和上述“没有设置 Local 字符集”相同QString::fromLocal8Bit()此时本地字符集为 GBK则显示乱码直接输入、采用 QString::fromUtf8() 都能显示正常。
在 Qt5 中使用 QString::QStringLiteral 这个宏来处理中文乱码问题这个宏是官方提供专门处理乱码问题的。