近来用qt时,需要读取中文目录,但总是读取失败。
仔细查了后,找到了原因。
问题:
- windows的
默认编码
是ansi
。windows下,IDE不同,debugger采用的编码也不同 - QString默认使用是unicode,QString::toStdString(),这个操作是把utf16(也可能是utf32)
变成utf8编码,不是ansi编码
- Qt 和 std 并不考虑文件的编码,而是判断操作系统的默认编码
参考
使用QString类进行编码转换
Unicode、UTF-8、UTF-16之间的区别
网上查到,有人建议windows下直接使用
QString::fromLocal8Bit("中文内容")
可解决中文乱码。
经测试,这行代码和文件编码有关,如果文件是ansi编码,是可以的,如果文件是utf8编码,反而会导致乱码
测试代码
#include <QDebug>
#include <QString>
#include <QDir>
#include <boost/filesystem.hpp>
bool exists(const std::string& path)
{
return boost::filesystem::exists(path);
}
int main()
{
/// !!!!!!!!!!!!!!!!!!!!!
/// !!! 笔者使用utf8格式的代码文件,使用ansi格式代码,结果会不同
/// !!!!!!!!!!!!!!!!!!!!!
QString qstr = QString::fromLocal8Bit("测试目录"); // windows下ansi -> unicode
QDir dir;
dir.mkpath(qstr);
QString qstr2 = "测试目录2"; // 直接使用文件编码,即utf8
dir.mkpath(qstr2);
qDebug()<<qstr;
qDebug()<<qstr2;
std::cout<<"qstr "<<qstr.toStdString()<<(exists(qstr.toStdString())?" yes ": " no ")<<std::endl;
std::cout<<"qstr2 "<<qstr2.toStdString()<<(exists(qstr2.toStdString())?" yes ": " no ")<<std::endl;
ECB::String s = qstr2.toLocal8Bit().data(); // 文件编码utf8,所以这行使用的是 utf8 -> ansi 编码转换
std::cout<<"local 8bit qstr2 "<<s<<(exists(s)?" yes ": " no ")<<std::endl;
ECB::String s2 = qstr2.toStdString(); // 文件编码utf8,所以s2 使用utf8编码
std::cout<<"to-std-str qstr2 "<<s2<<(exists(s2)?" yes ": " no ")<<std::endl;
return 0;
}
笔者用visual studio 和 qtcreator 测试了代码,两者cmd输出结果相同
。但debugger时因为默认编码不同内容不同
用visual studio 测试代码,输出如下:
用qtcreator 测试代码,输出如下:
debug窗口内容如下