QSettings与中⽂(反斜杠转义)
QSettings 与中⽂
本⽂介绍的是QSettings的 IniFormat 截⽌⽬前(Qt4.7)对中⽂的⽀持情况,如果你想实现⾃⼰定义格式(⽐如"[中⽂] 中⽂=中⽂"这样),可参看Qt4.4(包含)之前
先看个例⼦:
#include <QtCore/QCoreApplication>
#include <QtCore/QSettings>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QString value = QString::fromLocal8Bit("我是汉字");
QSettings settings("config.ini", QSettings::IniFormat);
settings.setValue("setcion/key", value);
return 0;
}
结果如下:
[setcion]
key=\x6211\x662f\x6c49\x5b57
这⼉Value部分显⽰的是上⾯4个汉字的UCS2(即UTF-16)编码。如果你喜欢,你可以叫它“乱码”。
为什么四个汉字变成这个样⼦了呢?
因为4个汉字的Unicode编码超出了ASCII码的范围,⽽将其序列化的话,有很多种不同的⽅案,⽽这些不同的⽅案中,对特定的⼈来说,只有⼀种⽅案是最合适的,其他的可能都被这特定的⼈称作乱码。
众⼝难调啊?怎么办,那就不调了呗。直接给出UTF-16编码,这样⼀来,尽管每个⼈都不太喜欢,但
总⽐让多数⼈都扫兴要好得多。
Qt4.5的转变
从Qt4.5开始,QSettings提供了⼀个新的成员函数,setIniCodec。这样⼀来,各种⾮ASCII码的⽤户应该⾼兴⼀点了,喜欢什么编码⾃⼰来设置,⽽不⽤考虑什么国际⽤户。
对简体中⽂⽤户来说,GBK还是UTF-8任意选择⼀个⾃⼰喜欢的就⾏了:
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QString value = QString::fromLocal8Bit("我是汉字");
QSettings settings("config.ini", QSettings::IniFormat);
#ifdef LOVE_GBK
settings.setIniCodec("GB2312");
#else
settings.setIniCodec("UTF8");
#endif
settings.setValue("setcion/key", value);
return 0;
}
结果如下:
[setcion]
key=我是汉字Key中的中⽂
截⽌到⽬前的Qt4.6.3,Key 和Section的中⽂仍不能使⽤本地编码,⽐如:
#include <QtCore/QCoreApplication>
#include <QtCore/QSettings>
#include <QtCore/QStringBuilder>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QString section = QString::fromLocal8Bit("节");
QString key = QString::fromLocal8Bit("键");
QString value = QString::fromLocal8Bit("我是汉字");
QSettings settings("config.ini", QSettings::IniFormat);
settings.setIniCodec("UTF-8");
settings.setValue(section%"/"%key, value);
return 0;
}
注意:此处字符串连接⽤的Qt4.6引⼊的%,如果是之前的版本,换成+并删除相应头⽂件即可。
结果如下:
[%U8282]
%U952E=我是汉字
同⼀开始的Value⼀样,Key和Section中⾮ASCII字符的仍会进⾏转义,此处我们看到的就是%U后跟UTF-16的数值。该部分不受setIniCodec的影响。
不⽌中⽂这样
其实不⽌中⽂是这样,Qt对传统的Latin系列编码也没有特殊的照顾
当Section Key Value中出现Latin字符时,同样将进⾏转义。⽐如:
#include <QtCore/QStringBuilder>
int main(int argc, char **argv)
{
QCoreApplication app(argc, argv);
QString section = QString::fromLocal8Bit("ÀÁ");
QString key = QString::fromLocal8Bit("ÀÁ");
QString value = QString::fromLocal8Bit("ÀÁ");
QSettings settings("config.ini", QSettings::IniFormat);
settings.setValue(section%"/"%key, value);
return 0;
}
结果:
[%E0%E1]
%E0%E1=\xe0\xe1Settings源码
%QTDIR%\src\corelib\io\qsettings.cpp
QSettings的数据在内存中存放于 QMap<QString, QVariant> 中,读写⽂件也就是将⽂件读⼊该Map和从该Map写⼊⽂件的过程。ini⽂件的写⼊
bool QConfFileSettingsPrivate::writeIniFile(QIODevice &device, const ParsedSettingsMap &map
)
Key的写⼊相对⽐较简单,因为本⾝就是字符串,只需序列化即可(对'0'-'9', 'a'-'z', 'A'-'Z', '_', '-', '.'之外的字符进⾏转义处理)。
void QSettingsPrivate::iniEscapedKey(const QString &key, QByteArray &result)
Value的写⼊就很复杂了,分两步⾛:
将 QVariant 变成 QString 或 QStringList
StringList 和 List 型 ==> QStringList,其他转成QString
直接转成字符串的 String LongLong Int Bool Double ...
包含可读信息但不可直接转的 Rect Size Point ...
包含⾮可读信息的 ByteArray
Invalid 型的 QVariant
其他 QVariant
将字符串序列化
主要是对字符的Escape,⽐如'\0','\a'等控制字符,变成"\\0", "\\a"等
其他控制字符,"\\x.."
⼤于 7F 的字符,如有codec,则使⽤codec,如⽆,则⽤"\\x...."
字符串内包含';', ',', '='时,字符串两段加引号
字符'\0', "\x.."之后如果是数字(0-9a-fA-F),要继续如此处理
unicode汉字
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论