zoukankan      html  css  js  c++  java
  • Qstring中文乱码问题

    首先呢,声明一下,QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString。
    很简单的问题,"我是中文"这样写的时候,它是传统的 char 类型的窄字符串,我们需要的只不过是通过某种方式告诉QString 这四个汉字采用的那种编码。

    #include <QtGui/QApplication>
    #include <QtGui/QLabel>
    
    intmain(intargc, char **argv)
    {
    QApplicationapp(argc, argv);
    QStringa= "我是汉字";
    QLabellabel(a);
    label.show();
    returnapp.exec();
    }
    
    ÎòêÇoo×Ö
    我æ˜ˉæ±‰å —
    

    出乎意料,界面上中文没显示出来,出现了不认识字符。 于是开始用搜索引擎搜索,开始上论坛发帖或抱怨
    最后被告知,下面的语句之一可以解决问题:

    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    两条指令挨个一试,确实可以解决(多数用户是第一条,其他用户是第二条)。那么,为什么会这样呢?

    QString 为什么会乱码呢?真的是 QString 乱码了吗?我们可以问问自己,我们抱怨的对象是不是搞错了?

    继续之前,先明确几个概念:

    明确概念0
    "我是汉字" 是C语言中的字符串,它是char型的窄字符串。上面的例子可写为

    const char * str = "我是汉字";
    QString a= str;
    或
    char str[] = "我是汉字";
    QString a= str;
    

    明确概念1
    源文件是有编码的,但是这种纯文本文件却不会记录自己采用的编码
    这个是问题的根源,不妨做个试验,将前面的源代码保存成GBK编码,用16进制编辑器能看到引号内是ce d2 ca c7 ba ba d7 d6这样8个字节。

    现在将该文件拷贝到正体(繁体)中文的Windows中,用记事本打开会什么样子呢?

    ...
    QStringa= "扂岆犖趼";
    QLabellabel(a);
    label.show();
    ...

    那么放到欧美人的Windows系统中,再用记事本打开呢?
    ...
    QStringa= "ÎòêÇoo×Ö";
    QLabellabel(a);
    label.show();
    ...
    同一个文件,未做任何修改,但其中的8个字节ce d2 ca c7 ba ba d7 d6,对用GBK的大陆人,用BIG5的港澳台同胞,以及用Latin-1的欧洲人看来,看到的却是完全不同的文字。

    明确概念2
    如同我们都了解的'A'与'x41'等价一样。
    GBK编码下的

    const char * str = "我是汉字"
    等价于
    const char * str = "xcexd2xcaxc7xbaxbaxd7xd6";

    当用UTF-8编码时,等价于
    const char * str = "xe6x88x91xe6x98xafxe6xb1x89xe5xadx97";
    注意:这个说法不全对,比如保存成带BOM的UTF-8,用cl编译器时,汉字本身是UTF-8编码,但程序内保存时却是对应的GBK编码。

    明确概念3
    QString 内部采用的是Unicode。(几乎可以存放任何字符)
    QString内部采用的是 Unicode,它可以同时存放GBK中的字符"我是汉字",BIG5中的字符"扂岆犖趼" 以及Latin-1中的字符"ÎòêÇoo×Ö"。

    重点!!!!!
    所以如果QString解析到的 "我是汉字"这几个字符是以big5或者Latin解析,那么就会输出乱码

    解决

    该怎么转换成Unicode并存到 QString 内?按照GBK、BIG5、Latin-1还是其他方式...

    QString 工作方式
    const char * str = "我是汉字";
    QString a= str;
    其实很简单的一个问题,当你需要从窄字符串 char* 转成Unicode的QString字符串的,你需要告诉QString你的这串char* 中究竟是什么编码?GBK、BIG5、Latin-1


    理想情况就是:将char* 传给QString时,同时告诉QString自己的编码是什么:
    就像下面的函数一样,QString的成员函数知道按照何种编码来处理 C 字符串

    QString QString::fromAscii ( const char * str, int size = -1 )
    QString QString::fromLatin1 ( const char * str, int size = -1 )
    QString QString::fromLocal8Bit ( const char * str, int size = -1 )
    QString QString::fromUtf8 ( const char * str, int size = -1 )
    单QString 只提供了这几个成员函数,远远满足不了大家的需求,比如,在简体中文Windows下,local8Bit是GBK,可是有一个char串是 BIG5 或 Latin-2怎么办?

    二、
    那就动用强大的QTextCodec吧,首先QTextCodec肯定知道自己所负责的编码的,然后你把一个char串送给它,它就能正确将其转成Unicode了。
    QString QTextCodec::toUnicode ( const char * chars ) const

    三、
    可是这个调用太麻烦了,我就想直接这样用怎么办?
    QString a= str;或QString a(str);

    这样一来肯定没办法同时告诉 QString 你的str是何种编码了,只能通过其他方式了。这也就是开头提到的
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

    设置QString默认采用的编码。而究竟采用哪一个,一般来说就是源代码是GBK,就用GBK,源代码是UTF-8就用UTF-8。
    -------------------------------------- 适合自己的才是最好的!-----------------------------------------
  • 相关阅读:
    一文学会Go语言
    只用120行Java代码写一个自己的区块链
    精通libGDX游戏开发-RPG实战-欢迎来到RPG的世界
    精通libGDX游戏开发-RPG实战-开发游戏的基本前提
    libGDX开发环境搭建-Android Studio 最新版
    linux下redis的最佳实践(Master-Slave)
    使用Redis实现高并发分布式序列号生成服务
    [libGDX游戏开发教程]使用libGDX进行游戏开发(12)-Action动画
    [libgdx游戏开发教程]使用Libgdx进行游戏开发(11)-高级编程技巧 Box2d和Shader
    [libgdx游戏开发教程]使用Libgdx进行游戏开发(10)-音乐和音效
  • 原文地址:https://www.cnblogs.com/retry/p/14918602.html
Copyright © 2011-2022 走看看