Qt | QTextCodec类使用详解、GBK和UTF8编码互转、QString的toLocal8bit和toLatin1区别
创始人
2024-04-15 14:46:40
0

Qt | QTextCodec类使用详解、GBK和UTF8编码互转、QString的toLocal8bit和toLatin1区别


目录

  • Qt | QTextCodec类使用详解、GBK和UTF8编码互转、QString的toLocal8bit和toLatin1区别
      • 1、QTextCodec简介及使用
        • 1.1 编码之间的转换
        • 1.2 解决中文显示乱码问题
      • 2、QString的toLocal8bit和toLatin1


1、QTextCodec简介及使用

1.1 编码之间的转换

Qt使用Unicode来存储、绘制和操作字符串。

unicode是各个编码格式转换的媒介,以UTF-8转到GBK格式为例,需要先将UTF-8转到UNICODE,在通过unicode转到GBK,反之亦然。

Qt提供了一组QTextCodec类,以帮助将非Unicode格式转换为Unicode格式。您还可以创建自己的编解码器类。

支持的编码包括:

  • Big5
  • Big5-HKSCS
  • CP949
  • EUC-JP
  • EUC-KR
  • GB18030
  • HP-ROMAN8
  • IBM 850
  • IBM 866
  • IBM 874
  • ISO 2022-JP
  • ISO 8859-1 to 10
  • ISO 8859-13 to 16
  • Iscii-Bng, Dev, Gjr, Knd, Mlm, Ori, Pnj, Tlg, and Tml
  • KOI8-R
  • KOI8-U
  • Macintosh
  • Shift-JIS
  • TIS-620
  • TSCII
  • UTF-8
  • UTF-16
  • UTF-16BE
  • UTF-16LE
  • UTF-32
  • UTF-32BE
  • UTF-32LE
  • Windows-1250 to 1258

注:gb18030字符集兼容了gbk字符集,以两个字节表示一个文字。

现在假设有一组GBK格式的数据,需要转为unicode格式字符串,那么可以这样:

    QByteArray encodedString = "...";QTextCodec *codec = QTextCodec::codecForName("GBK");QString string = codec->toUnicode(encodedString);

同样的,如果现在有一组unicode字符串需要转为GBK码数据,那么就是这样:

    QString string = "...";QTextCodec *codec = QTextCodec::codecForName("GBK");QByteArray encodedString = codec->fromUnicode(string);

以上为简单的使用,还有一个经常遇到的问题就是Qt在windows和linux下中文显示乱码的问题。

1.2 解决中文显示乱码问题

很多新手直接网上一查就是下面三句解决中文乱码问题:

    QTextCodec* codec = QTextCodec::codecForName("GBK");// 或者QTextCodec* codec = QTextCodec::codecForName("gb18030 或 gbk 或 utf8");QTextCodec::setCodecForCStrings(codec);  // 在qt5中不存在QTextCodec::setCodecForTr(codec);        // 在qt5中不存在QTextCodec::setCodecForLocale(codec);

这三个函数的作用如下:

setCodecForCStrings(codec):设置QString用于转换const char*和QByteArrays的编解码器。如果编解码器为0(默认值),QString将采用Latin-1。

setCodecForTr(codec):设置QObject::tr()的编码器。如果codec为0(默认值),tr()将采用Latin-1。

setCodecForLocale(codec):将本地编解码器设置为codec,可以由codecForLocale函数返回。如果c是空指针,则编解码器将重置为默认值。对于一些希望使用自己的机制来设置区域设置的应用程序来说,这个功能会有用。

加上这三句后发现真的解决了中文乱码问题!!(固定系统、固定地区语言设置、固定编译环境)。

但是这么干是不对滴!可能换了个系统还是出问题!

那么这三句到底有何作用?下面就详细说一下。

// 获取编解码器名称
qDebug() << QTextCodec::codecForLocale()->name();  // windows下打印GBK,linux下打印utf8

在编写Qt代码的时候使用中文字符串的时候一般会有这三种形式,分别为const char*这种C格式的字符串、QString()进行构造的形式、tr()进行构造的形式:

    QString s1 = "你好";       // 形式1QString s2("你好");        // 形式2QString s3 = tr("你好");   // 形式3

setCodecForCStrings就是设置的形式一和形式二所用的编码器。

setCodecForTr就是设置使用tr()函数时的所用的编码器。

在Qt4中,如果你没有使用setCodecForCStrings和setCodecForTr指定编解码的方式,那么就会采用Latin-1格式,也就是ASCII。

此时将<你好>这两个中文汉字传入QString,这两个汉字不存在于Latin-1字符集里,自然是会乱码显示,这就是原因!

到了Qt5中,就把setCodecForCStrings和setCodecForTr给去掉了,并将QString()的构造函数默认调用的是fromUTF8,且Qt Creator的文件编码格式默认为UTF-8。

可以从这里看:工具->选项->文本编辑器

而对于使用VS的用户来说,默认编码或者你设置的编码可能是不是UTF8,所以出现了中文显示乱码的问题!这就是Qt5下中文显示乱码的原因!


2、QString的toLocal8bit和toLatin1

QString的toLocal8bit和toLatin1都可以将QString转化为QByteArray,但是两者的区别在于编码的不同。

  • toLocal8Bit:转为本地8bit编码格式。如果字符串包含本地8位编码不支持的字符,则返回的字节数组未定义。前面说过Qt使用Unicode来存储、绘制和操作字符串,执行。执行toLocal8Bit就相当于将unicode编码的qstring转为了本地编码格式,对于windows系统,本地编码格式为GBK,linux系统为UTF-8。

  • toLatin1:以QByteArray的形式返回字符串的Latin-1表示形式。也就是转为了ASCII编码。如果字符串包含非Latin1字符,则返回的字节数组未定义。这些字符可以被抑制或替换为问号。

下面进行示例演示。

    QString s = "你好";qDebug() << s.size();                // 输出2(qt用unicode编码格式组织QString)qDebug() << s;qDebug() << s.toUtf8().size();       // 输出6(UTF8用三个字符表示一个汉字)qDebug() << s.toUtf8();              // 转utf8qDebug() << s.toLocal8Bit().size();  // 输出4(window下默认编码格式为GBK,一个GBK汉字占两个字节)qDebug() << s.toLocal8Bit();         // 转本地编码,也就是GBK格式qDebug() << s.toLatin1().size();     // 输出2qDebug() << s.toLatin1();            // 转ASCII格式,由于汉字不存在于ASCII编码中,所以会输出两个问号

程序运行结果:


ends…

相关内容

热门资讯

前端-session、jwt 目录:   (1)session (2&#x...
linux入门---制作进度条 了解缓冲区 我们首先来看看下面的操作: 我们首先创建了一个文件并在这个文件里面添加了...
关于测试,我发现了哪些新大陆 关于测试 平常也只是听说过一些关于测试的术语,但并没有使用过测试工具。偶然看到编程老师...
前缀和与对数器与二分法 1. 前缀和 假设有一个数组,我们想大量频繁的去访问L到R这个区间的和,...
nodejs:本地安装nvm实... 一、背景-使用不同版本node的原因 vue3+ts、nuxt3版本,node...
JAVA集合知识整理 Java集合知识整理 HashMap相关 HashMap的底层数据结构:jdk1.8之...
无刷直流电机介绍及单片机控制实... 无刷直流电机介绍及单片机控制实例前言基本概念优势与劣势使用寿命基本结构使用单片机控制实例电子调速器&...
fwdiary(2) dp2 1.传纸条  AcWing 275. 传纸条 - AcWing 走两条路,走一条最大的...
常用的DOS命令 常用的DOS命令 DOS(Disk Operating System,磁...
<C++> 类和对象(下) 1.const成员函数将const修饰的“成员函数”称之为const成员函数,cons...