c++中文编码问题

std::string或者const char*,本质上都是二进制,不包含编码属性,其编码信息来源于赋值语句,

QString以utf16编码,默认构造或赋值的字面量假定为utf8,若是其它编码比如ansi,可以调用QString::fromLocal8bit

一、字面量的编码取决于文件,即如果在c++源文件中有直接赋值

1)、const char* s="中文";或者std::string str="中文",该源文件是什么编码,则结果就是什么编码。

2)、QString默认以utf-16编码,默认赋值假定为utf8,即:若源文件为utf8编码,则QString qStr="中文"

  若源文件为ansi,则QString qStr=QString::fromLocal8bit(”中文")

可以用记事本打开源文件,点另存为

二、printf和std::cout的编码取决于codepage,windows默认为ansi,查看方式,点左上角,属性

控制台应用,可以通过在main开始处设置utf8:

system("chcp 65001");//utf-8

三、main的argv到底是什么编码----ansi,无论调用system("chcp 65001")否。

四、调试过程中只能显示ansi,如果const char* 或者std::string编码为utf8,调试显示会乱码

解决方式:可在watch中查看该变量,后加",s8"

五、qt 5.15 后,QString::toStdString()和qDebug()默认调用toUtf8(),即将utf16转换为utf8。

  QTextCodec::setCodecForLocale只对QString::toLocalUtf8发生作用,

  中文操作系统默认: QTextCodec::setCodecForLocale(QTextCodec::codecForName("GBK"));

六、gdal:

  CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES/NO");

  若为YES,则假定函数接收的路径变量为utf8编码的,否则为ansi的。

七、osg:

  若在CMake编译的时候就选择OSG_USE_UTF8_FILENAME选项,则osgdb命名空间里read write路径均假定为utf8,否则为ansi

例:

int main(int argc, char* argv[]) {
#if 1
CPLSetConfigOption("GDAL_FILENAME_IS_UTF8", "YES");
GDALAllRegister();
//system("chcp 65001");

if (argc < 10)return 0;
//因为argv编码与源文件编码无关,一定为ansi,而qstring赋值语句默认接受utf8,因此需调用fromLocal8Bit
QString tiffPath =QString::fromLocal8Bit( argv[10]);//假定tiff路径存在命令行第10个参数中
//qDebug()解码为utf8
qDebug() << tiffPath.toStdString().c_str();
//tiffPath为utf16编码,toStdString默认调用toUtf8,则接受的输入符合GDAL_FILENAME_IS_UTF8=YES
GDALDataset* tiffDs=(GDALDataset *) GDALOpen(tiffPath.toStdString().c_str(), GDALAccess::GA_ReadOnly);

////一、源文件为utf编码时:
////因为源文件是utf8编码,则osgPath也是utf8编码,此时调试osgPath显示乱码,可watch ,s8
//std::string osgPath = "D:\\osgdataTest\\OSGB\\OSGB中\\Data\\rootMerge\\rootMerge.osgb";
////因为之前设置了system("chcp 65001"),则可正确显示中文
//std::cout << osgPath << "\n";

//二、源文件为ansi编码时:
//因为源文件是ansi编码,则osgPath也是ansi编码,此时调试osgPath显示正确
std::string osgPath = "D:\\osgdataTest\\OSGB\\OSGB中\\Data\\rootMerge\\rootMerge.osgb";
//fromLocal8Bit将ansi转换为utf16,toStdString再转换为utf8
osgPath = QString::fromLocal8Bit(osgPath.c_str()).toStdString();
//因为之前设置了system("chcp 65001"),则可正确显示中文
std::cout << osgPath << "\n";



//若osg库是打开utf8编译选项的,则以下可以执行
osg::Node* node = osgDB::readNodeFile(osgPath);


return 0;

#endif

}

以上一二分别对应源文件为utf8编码或者ansi编码

posted @ 2024-05-06 17:21  jwwry  阅读(36)  评论(0编辑  收藏  举报