• 9291阅读
  • 9回复

请教关于编码解码问题!!!!!!!!难 [复制链接]

上一主题 下一主题
离线iiiyyyhhhsss
 

只看楼主 倒序阅读 楼主  发表于: 2010-05-29
通常:
qDebug()<<QString("我们");
会出现乱码..
那是因为,qt默认的编码方式不是我们平时中文操作系统平台使用的"gb18030";

因此,通常需要借助使用以下的解码器:
QTextCodec *co=QTextCodec::codecForName("gb18030");
qDebug()<<co->toUnicode("我们");



那么,我想问(关键):
qt里默认的编码方式是什么?是不是Ascii?

如果是,为什么QTextCodec *co=QTextCodec::codecForName("ascii");会抱错?

如果不是,又是默认什么编码方式?













离线rcyboom

只看该作者 1楼 发表于: 2010-05-29
打开qtcreator选择edit-select encoding看看就知道了,一般情况下默认都是utf-8
离线dbzhang800

只看该作者 2楼 发表于: 2010-05-30
引用楼主iiiyyyhhhsss于2010-05-29 18:30发表的 请教关于编码解码问题!!!!!!!!难 :
通常:
qDebug()<<QString("我们");
会出现乱码..
那是因为,qt默认的编码方式不是我们平时中文操作系统平台使用的"gb18030";
因此,通常需要借助使用以下的解码器:
QTextCodec *co=QTextCodec::codecForName("gb18030");
qDebug()<<co->toUnicode(" 我们");

还是建议你认真看看manual,这种问题只要概念清晰还是蛮简单的。出现乱码是因为写 QString("我们") 时 就没好好看过manual,没想过这是调用的哪个构造函数。

出现中文,那么首先要清楚编辑器采用的什么编码,这点和系统其实关系不大(当然,像简体中文windows下很多编辑器都只支持默认 gbk的,而记事本之流支持utf8却老会默认添加BOM而导致问题无法编程时使用,这都会造成编码和系统相关的误解)

考虑
  1. QString("我们");

如果你的编辑器用的gbk编码,那么
它等价于
  1. QString("\xce\xd2\xc3\xc7");


如果你的编辑器用的utf8编码,那么
它等价于
  1. QString("\xe6\x88\x91\xe4\xbb\xac");


大家都知道 QString 内部是unicode,当我们想把 char * 转成 unicode时,肯定要知道这串char * 是什么编码:ascii、latin1、gbk、big5、utf8 还是其他。并且将编码告诉该构造函数才有可能工作。


其实,即使我们对编码不感兴趣,当调用
  1. QString::QString ( const char * str )

这个构造函数时,认真看看它的manual也不算为过吧?manual中怎么写的:

QString::QString ( const char * str )
Constructs a string initialized with the 8-bit string str. The given const char pointer is converted to Unicode

using the fromAscii() function.


它告诉你这个其实调用的是 QString::fromAscii,这个函数又是怎么工作的,manual中有更详细的介绍:

QString QString::fromAscii ( const char * str, int size = -1 )   [static]

Returns a QString initialized with the first size characters of the 8-bit string str.
If size is -1 (default), it is taken to be qstrlen(str).
Note that, despite the name, this function actually uses the codec defined by QTextCodec::setCodecForCStrings() to convertstr to Unicode. Depending on the codec, it may not accept valid US-ASCII (ANSI X3.4-1986) input. If no codec has been set, this function does the same as fromLatin1().

很清楚吧? 它告诉你,如果你没有设置 CodecForCStrings ,那么它调用的是 fromLatin1。如果你想用 gbk 或 utf8 等编码,请设置。

题外:
不少同学喜欢在设计ui界面时,直接在里面属于中文,比如,一个label中输入中文 "我们",uic 是怎么处理的呢?用支持utf8的编辑器打开 .ui 文件,你能从中看到“我们”两个汉字。用编辑器打开 uic 生成的 ui_***.h 文件,你会发现找不到汉字了,取代的是
  1. label->setText(QString::fromUtf8("\346\210\221\344\273\254"));


  1. label->setText(QApplication::translate("Dialog", "\346\210\221\344\273\254", 0, QApplication::UnicodeUTF8));

这种写法。
可为什么会这么处理呢?结合上面提到的,我想大家能想明白^_^



引用楼主iiiyyyhhhsss于2010-05-29 18:30发表的 请教关于编码解码问题!!!!!!!!难 :
通常:
那么,我想问(关键):
qt里默认的编码方式是什么?是不是Ascii?

如果是,为什么QTextCodec *co=QTextCodec::codecForName("ascii");会抱错?

如果不是,又是默认什么编码方式?

这个问题,上面其实已经回复了。针对你说的报错问题,当调用 QTextCodec::codecForName ( const char * name ),我们应该去想,name 的值可以随便指定么?指定一个“hahaha”它能工作么?如果不是,怎么获得去names的列表,这个,manual 中有介绍
[ 此帖被dbzhang800在2010-05-30 10:07重新编辑 ]
离线luoyes

只看该作者 3楼 发表于: 2010-05-30
mark
离线jialrs
只看该作者 4楼 发表于: 2010-05-30
我也被整的很纠结。。。。dbzhang800大虾讲解的还是听有条理的。。。
离线iiiyyyhhhsss

只看该作者 5楼 发表于: 2010-05-30
回 2楼(dbzhang800) 的帖子
thanks!!!

我已经知道了.

举例:
当使用了QTextCodec::setCodecForCStrings("utf-8")时,QString("我们"),相当于QString::fromUtf8("我们");
当没有QTextCodec::setCodecForCStrings()时,qt会默认调用fromAscii(),此时也即调用fromLatin1();


但我查过,那个编码name列表里没有"Latin-1",也没有"Ascii",但以下这句却能正常使用...
QTextCodec::codecForName ("Latin-1")


更详细的一点:
若你的编辑器使用的是gbk编码,则
QString("我们")相当于QString("\xce\xd2\xc3\xc7");;;

若你的编辑器使用的是utf-8编码,则
QString("我们")相当于QString("\xe6\x88\x91\xe4\xbb\xac");













离线dbzhang800

只看该作者 6楼 发表于: 2010-05-30
Re:回 2楼(dbzhang800) 的帖子
引用第5楼iiiyyyhhhsss于2010-05-30 18:13发表的 回 2楼(dbzhang800) 的帖子 :
t
但我查过,那个编码name列表里没有"Latin-1",也没有"Ascii",但以下这句却能正常使用...
QTextCodec::codecForName ("Latin-1")


不清楚你提到的name是指的什么。

如果是说manual给出的
The supported encodings are:
...
    * 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

...

而认不出来 ISO 8859-1 就是 Latin1的话,就需要补补课了。


如果你运行了
  1. qDebug()<<QTextCodec::availableCodecs();

你应该得到类似下面的代码 (具体结果和你的Qt提供的解码插件有关),下面贴的是 windows 下Qt4.6 的默认结果

("GBK", "CP936", "MS936", "windows-936", "roman8", "hp-roman8", "csHPRoman8", "TIS-620", "ISO 8859-11", "WINSAMI2", "WS2", "Apple Roman", "macintosh", "MacRoman", "windows-1258", "CP1258", "windows-1257", "CP1257", "windows-1256", "CP1256", "windows-1255", "CP1255", "windows-1254", "CP1254", "windows-1253", "CP1253", "windows-1252", "CP1252", "windows-1251", "CP1251", "windows-1250", "CP1250", "IBM866", "CP866", "csIBM866", "IBM874", "CP874", "IBM850", "CP850", "csPC850Multilingual", "ISO-8859-16", "iso-ir-226", "latin10", "ISO-8859-14", "iso-ir-199", "latin8", "iso-celtic", "ISO-8859-13", "ISO-8859-10", "iso-ir-157", "latin6", "ISO-8859-10:1992", "csISOLatin6", "ISO-8859-9", "iso-ir-148", "latin5", "csISOLatin5", "ISO-8859-8", "ISO 8859-8-I", "iso-ir-138", "hebrew", "csISOLatinHebrew", "ISO-8859-7", "ECMA-118", "greek", "iso-ir-126", "csISOLatinGreek", "ISO-8859-6", "ISO-8859-6-I", "ECMA-114", "ASMO-708", "arabic", "iso-ir-127", "csISOLatinArabic", "ISO-8859-5", "cyrillic", "iso-ir-144", "csISOLatinCyrillic", "ISO-8859-4", "latin4", "iso-ir-110", "csISOLatin4", "ISO-8859-3", "latin3", "iso-ir-109", "csISOLatin3", "ISO-8859-2", "latin2", "iso-ir-101", "csISOLatin2", "KOI8-U", "KOI8-RU", "KOI8-R", "csKOI8R", "UTF-8", "ISO-8859-1", "latin1", "CP819", "IBM819", "iso-ir-100", "csISOLatin1", "ISO-8859-15", "latin9", "UTF-32LE", "UTF-32BE", "UTF-32", "UTF-16LE", "UTF-16BE", "UTF-16", "System", "Iscii-Mlm", "Iscii-Knd", "Iscii-Tlg", "Iscii-Tml", "Iscii-Ori", "Iscii-Gjr", "Iscii-Pnj", "Iscii-Bng", "Iscii-Dev", "TSCII", "GB18030", "GB2312", "EUC-JP", "ISO-2022-JP", "Shift_JIS", "JIS7", "SJIS", "MS_Kanji", "EUC-KR", "cp949", "Big5", "Big5-HKSCS", "Big5-ETen", "CP950")


上面红色部分都是你提到的 Latin-1 的同义词。
当你执行
  1. QTextCodec::codecForName ("Latin-1")

时,会和上面的编码挨个比较,比较时将忽略大小写,忽略除字符和数字外的任何字符,也就是说
"Latin - 1"
"LATIN-1"
"Latin1"
“lAtin    1”
等等
在Qt中都是有效的写法
[ 此帖被dbzhang800在2010-05-30 20:35重新编辑 ]
离线benbenmajia

只看该作者 7楼 发表于: 2010-05-31
我是来看张老师滴
安然.....
离线myseemylife

只看该作者 8楼 发表于: 2012-02-10
有条理~~~~~哇塞~~~学习了~~
蠢笨的愚钝~
离线rcyboom

只看该作者 9楼 发表于: 2012-02-10
学习了,一直知道怎么干但不知道为什么,现在知道了,谢谢!
快速回复
限100 字节
 
上一个 下一个