【发布时间】:2014-11-04 16:59:03
【问题描述】:
在我的程序中,用户可以在命令行上提供文件名或使用QFileDialog。在第一种情况下,我有一个没有任何编码信息的char*,在第二种情况下,我有一个QString。
为了存储文件名供以后使用(最近的文件),我需要它作为QString。但是要使用std::ifstream 打开文件,我需要std::string。
现在乐趣开始了。我能做到:
filename = QString::fromLocal8Bit(argv[1]);
稍后,我可以做到:
std::string fn = filename.toLocal8Bit().constData();
这适用于大多数角色,但不是全部。例如,单词Раи́са 在经过这种转换后看起来是一样的,但实际上有不同的字符。
所以虽然我可以有一个Раи́са.txt,它会显示Раи́са.txt,但它不会在文件系统中找到该文件。大多数字母都有效,但 и́ 无效。
(请注意,在QFileDialog 中选择文件时,它确实可以正常工作。当它来自命令行时,它不会。)
有没有更好的方法来保存文件名?现在我以任何本机编码获得它,并且可以在不知道它的情况下以相同的编码传递。至少我是这么认为的。
【问题讨论】:
-
为什么使用ifstream打开文件,而不是QFile?
-
文件在没有 Qt 依赖的不同模块中打开。它与 GUI 分离。
-
你为什么使用 QString::fromLocal8Bit ?从这个函数的文档中它说:“QTextCodec::codecForLocale() 用于执行从 Unicode 的转换。如果无法确定语言环境编码,则此函数与 toLatin1() 相同。”看起来在您的情况下 toLatin1() 最终被调用,当您稍后调用 toLocal8Bit() 时发生以下情况:“如果此字符串包含任何无法在语言环境中编码的字符,则返回的字节数组是未定义的。这些字符可能会被抑制或被另一个替换。”
-
如果您使用的是 Qt5,您是否尝试过 QString filename(argv[1]);后来只是 std::string fn = QByteArray(filename).constData();
-
@N1ghtLight 我也有同样的想法,但是他是在
QString filename中看到了正确的字符串,所以他的codecForLocale必须正确设置,因为如果toLatin1得到称为特殊字符的有:“用问号抑制或替换”。 qt-project.org/doc/qt-5/qstring.html#toLatin1
标签: qt character-encoding qstring