c++ - 从 lineEdit QT 获取 unicode 并将其写入文件
问题描述
我有一个有lineEdit
对象的代码。该对象以任何语言(无法选择哪种语言)进入它,因此它必须支持 Unicode。然后我必须将 Unicode 从中取出并将其写入文件。
我的问题是,lineEdit
将文本转换为纯 ASCII 并在我得到它之前将其放入QSring
,所以我一次又一次地收到垃圾邮件。
这是我正在尝试做的示例代码:
bool MainWindow::write_file(QString path, QString data)
{
QFile file( path );
if (file.open(QIODevice::WriteOnly))
{
QTextStream stream( &file );
stream << data.toUtf8() << endl; // tried this -> didn't work...
stream << data << endl;
}else
{
return false;
}
file.close();
return true;
}
void MainWindow::on_pushButton_clicked()
{
// ui->lineEdit->text bring to me the unicode into QString allready
// how can encode the data to utf-8 BEFORE it get into QString?
write_file(PYTHON_DB_COMMAND, ui->lineEdit->text());
}
解决方案
你把东西混在一起了。
Qt 绝对支持 Unicode;QLineEdit::text()
返回 a QString
,它是 UTF-16 代码单元的序列。你错的是后面的 IO 部分;特别是,您在滥用QTextStream
.
让我们把它放在一边。在这里写下 UTF-8 内容的简单方法就是打开QFile
并直接写入转换为 UTF-8 的字符串。
QFile file(path);
if (file.open(QIODevice::WriteOnly)) {
file.write(data.toUtf8());
file.putchar('\n');
}
StraightQFile
仅适用于字节序列,我们放入其中的内容会写入文件中(文本模式下的白痴换行翻译除外,但我离题了);data.toUtf8()
返回从 UTF-16 转换为 UTF-8 的字符串,并将其写入文件而不用大惊小怪。
那有什么关系QTextStream
呢?好吧,QTextStream
的工作是提供帮助以将类似文本的内容写入文件(在某种程度上,QTextStream
是QIODevice
什么std::ostream
是std::streambuf
1);因此,它提供了轻松输出QString
值的方法。
但是,QString
它是由 UTF-16 代码单元组成的,而底层文件是面向字节的,因此需要进行转换。为此,QTextStream
使用一个 internal QTextCodec
,如果没有显式设置 using setCodec
,则 isQTextCodec::codecFromLocale()
,在 Windows 系统上通常是一些遗留编码(例如 windows-1252),无法表示大部分 Unicode;因此输出中的问号。
即使显式使用QString::toUtf8()
并在其上写入结果QTextStream
也无济于事:由于它是为编写text量身定制的,因此它假定QByteArray
您传入的是 UTF-8 数据,因此它QString
使用它的fromUtf8
方法将其转换为 a ,然后将其写入(所以,它使用上述编解码器进行转换)。
因此,如果您想QString
使用 UTF-8 将数据写入文件,正确的方法QTextStream
是首先将其编解码器设置为 UTF-8,然后直接输出您QString
的 s:
QFile file(path);
if (file.open(QIODevice::WriteOnly)) {
QTextStream stream( &file );
stream.setCodec("UTF-8");
stream << data << endl;
}
顺便
- 通常不需要使用
endl
- 除了输出换行符之外,它还会强制文件刷新,这通常不是您真正需要的(如果输出多行,可能会降低写入性能); - 您不需要显式调用
close()
aQFile
- 它会在销毁时自动关闭(因此,在这种情况下,在您的方法结束时)。
笔记
不幸的是,这并不完全正确;
std::streambuf
是一个三头怪物,因为它包装了“关联字符序列”(=底层流,例如 OS 文件)和“受控字符序列”(=缓冲),QFile
与根据std::codecvt
语言环境方面进行代码页转换,从而完全混淆了事物的语义(是std::streambuf
字节序列还是文本字符序列?)并使实现复杂化。像往常一样,iostreams 仍然是如何不设计 IO 库的一个很好的参考。
推荐阅读
- react-native - `useState` 错误地链接了单个 Redux + React Native 组件的多个实例
- mysql - 有没有比这更有效的 JOIN 来获得正确的输出?
- c++ - 尝试使用重载运算符编写程序时出错
- flutter - 如何创建波浪小部件?
- python - 如何在 tkinter 中使用 Canvas 在不同的帧上获取两个图像?
- sql - 如何在 Teradata SQL 中生成自动数字以严格递增 1
- google-sheets - 如何在 Google 表格中创建带有 x 轴对数刻度的直方图
- vb.net - 如何将拆分整数放入二维数组中?
- amazon-web-services - 如何从 Saml2aws cli 会话中注销或强制登录
- django - 无法在 Django 中添加新的空白字段(DataError)