• 7634阅读
  • 2回复

QT、VC共用MYSQL的中文乱码问题 [复制链接]

上一主题 下一主题
离线dd970512
 
只看楼主 倒序阅读 楼主  发表于: 2010-02-27
声明:本人学习QT不到七天,QT的好多东西还不是很清楚,说的不对的,大家不要见笑。
QT版本:4.6.1
VC版本:VC6
MYSQL版本:5.0.22
本文要解决的问题:
已安装MYSQL5.0.22,数据库使用UTF-8编码。数据库中所有设计字符串的字段都是用binary类型(字段类型为什么不用varchar,数据库为什么不用GBK编码,呵呵,历史原因)。VC中向数据库的字符串字段写入中文,要求能在QT中读出并写到XML文件中,XML也采用UTF-8编码。

思路:
大家都知道在VC中默认的字符串都是ANSI格式的,如果不做任何转换就写到数据库的binary字段中,通过VC读出肯定不会有问题。但在QT中直接读出来就是乱码,网上说是因为QT默认的是UTF-8编码,我不知道是对不对。假设网上说的是对的,现在的问题就很明白了,其实就是ANSI与UTF-8之间的编码转换问题。

解决方法:
1 要么在VC中写数据库之前,将字符串转为UTF-8编码。
2 要么在QT读到字符串时,将其转为UTF-8编码。

因为项目原因,只能采取方法2:
因为对QT不熟悉,关于字符串编码的转换函数找的很费劲,最好摸索出一个方法,定义一个转换宏来处理:
#define ANSITOUTF8(a) QString::fromLocal8Bit(a.data()).toUtf8()

举例如下:
bool LoadStation(QSqlDatabase& db)
{
    QSqlQueryModel query;
    int i = 0;
    query.setQuery("select * from Station_Cfg_T", db);

    for(i = 0; i < query.rowCount(); i++)
    {
        g_stuSta.sid    = query.record(i).value("Station_ID").toInt();
        g_stuSta.name   = ANSITOUTF8(query.record(i).value("Station_Name").toByteArray());

        g_stuSta.disknum = query.record(i).value("Disk_Num").toInt();
        g_stuSta.disksize = query.record(i).value("Disk_Size").toInt();

        g_stuSta.smvsize = query.record(i).value("Smv_Size").toInt();
        g_stuSta.othersize = query.record(i).value("Other_Size").toInt();
        g_stuSta.tmsource = query.record(i).value("Time_Source").toInt();
        g_stuSta.storemode = query.record(i).value("Store_Mode").toInt();
       break;//不用奇怪,此表只有一行
    }
    printf("获取Station_Cfg_T %d 行内容!\n", i);
    return (i > 0);
}


但就这样仍然不行,在MAIN函数中加入如下三行(来自网上):
QTextCodec *codec = QTextCodec::codecForName("UTF-8");
QTextCodec::setCodecForCStrings(codec);
QTextCodec::setCodecForTr(codec);
看意思是设置编码格式为UTF-8,但如网上大侠所说,QT默认的是UTF-8编码,何必要进行设置呢,疑问?????
完整main示例如下:
int main(int argc, char *argv[])
{
    QCoreApplication a(argc, argv);

    QTextCodec *codec = QTextCodec::codecForName("UTF-8");
    QTextCodec::setCodecForCStrings(codec);
    QTextCodec::setCodecForTr(codec);

    printf("打印已安装的SQL驱动!\n");
    qDebug() << QSqlDatabase::drivers();

    printf("从数据库读取配置信息!\n");
    LoadCfgInfo();

    SaveCfgToXml("c:\\temp.xml");
    return a.exec();
}

顺便附上一个写XML的例子,从书上照搬的,呵呵。
bool SaveCfgToXml(QString path)
{
    if(path.isNull() || path.isEmpty())
        return false;

    QFile file(path);

    if(!file.open(QIODevice::WriteOnly | QIODevice::Truncate))
    {
        return false;
    }

    QDomDocument doc;
    QDomElement elem, root;
    QDomAttr attr;

    QDomProcessingInstruction instruction;


    instruction = doc.createProcessingInstruction("xml", "version=\"1.0\" encoding=\"UTF-8\"");

     doc.appendChild(instruction);

     root = doc.createElement("wea800");
     doc.appendChild(root);

     elem = doc.createElement("station_cfg_t");
     attr = doc.createAttribute("Station_ID");
     attr.setValue("1");//还不知道怎么将数字写到属性值中,呵呵,刚看到了,用QString::number(g_stuSta.sid)
     elem.setAttributeNode(attr);

     attr = doc.createAttribute("Station_Name");
     attr.setValue(g_stuSta.name.toUtf8());
     elem.setAttributeNode(attr);

     root.appendChild(elem);


     QTextStream out(&file);
     doc.save(out, 4);
    return false;
}
[ 此帖被dd970512在2010-02-27 11:52重新编辑 ]
离线shiyutang
只看该作者 1楼 发表于: 2010-02-27
转换编码最方便是使用libiconv库。
版权协议是LGPL,可以用于商业闭源软件。
离线wd007

只看该作者 2楼 发表于: 2010-02-28
在Windows平台上,默认的编码是GB18030;

在X11上,一般是UTF-8。
欢迎访问我的博客,一起学习提高
http://blog.csdn.net/qter_wd007
快速回复
限100 字节
 
上一个 下一个