c++ - Qt cpp - 将 QString 写入文本文件的简洁方法

标签 c++ qt iostream qstring

我需要找到一种干净快速的方法来在 .csv 文件中编写 QString。 我试过:

QString path= QCoreApplication::applicationDirPath() + QString("/myfile.csv");
QFile file(path);
QString mystring = "Hello, world!";    
if(!file.open(QIODevice::WriteOnly)){
        file.close();
    } else {
        QTextStream out(&file); out << mystring;
        file.close();
    }

但它在 myfile.csv

中为我写了 "????????"

最佳答案

由于 Andrey 尚未使用react,我将介入并提供一些有关 OP 问题的背景信息:

来自 Qt 文档。关于 QString :

The QString class provides a Unicode character string.

QString stores a string of 16-bit QChars, where each QChar corresponds one Unicode 4.0 character. (Unicode characters with code values above 65535 are stored using surrogate pairs, i.e., two consecutive QChars.)

来自 Qt 文档。关于 QTextStream::operator<<(const QString &string) :

Writes the string string to the stream, and returns a reference to the QTextStream. The string is first encoded using the assigned codec (the default codec is QTextCodec::codecForLocale()) before it is written to the stream.

关于 QTextStream 一般而言:

Internally, QTextStream uses a Unicode based buffer, and QTextCodec is used by QTextStream to automatically support different character sets. By default, QTextCodec::codecForLocale() is used for reading and writing, but you can also set the codec by calling setCodec(). Automatic Unicode detection is also supported. When this feature is enabled (the default behavior), QTextStream will detect the UTF-16 or the UTF-32 BOM (Byte Order Mark) and switch to the appropriate UTF codec when reading. QTextStream does not write a BOM by default, but you can enable this by calling setGenerateByteOrderMark(true).

所以,"???????"可能是 Hello, World!编码为 UTF-16UTF-32 OPs 查看工具(输出 "???????" )无法检测到这一点,甚至不支持这种编码。

Andrey Semenov的提示, 改为:

file.write(mystring.toUtf8());

转换 QString内容到UTF-8哪个

  • 由字节组成
  • ASCII相同关于前 127 ASCII字符。

QString::toUtf8() 返回 QByteArray ;和 QTextStream::operator<<(const QByteArray&) 很可能将这些字节原封不动地写入。 (文档中甚至没有提到这一点。)

所以,Hello, World!仅包含 ASCII 表中可用的字符(代码 < 127)。即使,如果 OPs 查看工具支持/期望,例如Windows 1252它不会注意到这一点。 (我假设无法检测/处理 UTF-16 或 UTF-32 的工具可能也无法检测/处理 UTF-8。)


顺便说一句。找出编码 "???????"实际上是,myfile.csv可以使用十六进制 View 工具查看。由于输入是已知的,因此可以从输出中推断出编码。 (例如 He 在 ASCII UTF-8 中是 0x48 0x65,但在 UTF-16LE 中是 0x48 0x00 0x65 0x00 而在 UTF-16BE 中是 0x00 0x48 0x00 0x65。)


我尝试使用 MCVE 重现该问题.

testQTextStreamEncoding.cc :

#include <QtWidgets>

int main(int, char**)
{
  const QString qString = "Hello, World!";
  const QString qPath("testQTextStreamEncoding.txt");
  QFile qFile(qPath);
  if (qFile.open(QIODevice::WriteOnly)) {
    QTextStream out(&qFile); out << qString;
    qFile.close();
  }
  return 0;
}

testQTextStreamEncoding.pro :

SOURCES = testQTextStreamEncoding.cc

QT += widgets

关于 cygwin ,我做了:

$ qmake-qt5

$ make
g++ -c -fno-keep-inline-dllexport -D_GNU_SOURCE -pipe -O2 -Wall -W -D_REENTRANT -DQT_NO_DEBUG -DQT_WIDGETS_LIB -DQT_GUI_LIB -DQT_CORE_LIB -I. -isystem /usr/include/qt5 -isystem /usr/include/qt5/QtWidgets -isystem /usr/include/qt5/QtGui -isystem /usr/include/qt5/QtCore -I. -I/usr/lib/qt5/mkspecs/cygwin-g++ -o testQTextStreamEncoding.o testQTextStreamEncoding.cc
g++  -o testQTextStreamEncoding.exe testQTextStreamEncoding.o   -lQt5Widgets -lQt5Gui -lQt5Core -lGL -lpthread 

$ ./testQTextStreamEncoding

$ hexdump.exe -C testQTextStreamEncoding.txt
00000000  48 65 6c 6c 6f 2c 20 57  6f 72 6c 64 21           |Hello, World!|
0000000d

$

所以,看来我无法在我这边重现 OP 所描述的内容。 我还尝试了在 VS2013 中编译和运行的代码:

$ rm testQTextStreamEncoding.txt ; ls testQTextStreamEncoding.txt
ls: cannot access 'testQTextStreamEncoding.txt': No such file or directory

(在VS2013中编译、运行)

$ hexdump.exe -C testQTextStreamEncoding.txt
00000000  48 65 6c 6c 6f 2c 20 57  6f 72 6c 64 21           |Hello, World!|
0000000d

$

同样,我无法重现。看看 OP 如何产生 "???????" 会很有趣以及它实际包含的内容。

关于c++ - Qt cpp - 将 QString 写入文本文件的简洁方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49487712/

相关文章:

c++ - 不同的 32 位转换为 long/__int64,为什么?

c++ - 创建链接 vector 和列表

c++ - 使用基本数据类型计算 C++ 中的阶乘项

c# - StreamWriter 没有将最后几个字符写入文件

c++ - 运行最简单的 C++ 程序时出现 AVG Access Denied 警告

c++ - Boost::Test:编译并运行一个 "hello world"程序

python - Phonon 的 VideoWidget 在 QGLWidget(Qt,Python)上显示错误的颜色

c++ - 在循环的每次迭代处停止代码执行几毫秒

c++ - 在不生成新 QMovie 的情况下更改 GIF 动画速度

c++ - 使用 std::cout 的表格布局