Qt cpp - 将QString写入文本文件的干净方法
Qt cpp - Clean way to write QString into text file
我需要找到一种干净快速的方法.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
由于安德烈还没有反应,我将介入并提供一些有关 OP 问题的背景信息:
来自Qt文档关于QString
:
QString 类提供了一个 Unicode 字符串。
QString 存储一串 16 位 QChar,其中每个 QChar 对应一个 Unicode 4.0 字符。(代码值高于 65535 的 Unicode 字符使用代理项对存储,即两个连续的 QChar。
来自Qt文档关于QTextStream::operator<<(const QString &string)
:
将字符串字符串写入流,并返回对 QTextStream 的引用。在将字符串写入流之前,首先使用分配的编解码器(默认编解码器为 QTextCodec::codecForLocale())对字符串进行编码。
关于一般QTextStream
:
在内部,QTextStream 使用基于 Unicode 的缓冲区,QTextStream 使用 QTextCodec 自动支持不同的字符集。默认情况下,QTextCodec::codecForLocale() 用于读取和写入,但您也可以通过调用 setCodec() 来设置编解码器。还支持自动 Unicode 检测。启用此功能(默认行为)后,QTextStream 将检测 UTF-16 或 UTF-32 BOM(字节顺序标记),并在读取时切换到相应的 UTF 编解码器。默认情况下,QTextStream 不会写入 BOM,但您可以通过调用 setGenerateByteOrderMark(true) 来启用它。
因此,"???????"
可能Hello, World!
以 UTF-16 或 UTF-32 编码,其中 OPs 视图工具(输出"???????"
)无法检测到这一点,甚至不支持这种编码。
安德烈·谢苗诺夫的暗示,改为:
file.write(mystring.toUtf8());
将QString
内容转换为 UTF-8
- 由字节组成 与 ASCII
- 在前 127 个 ASCII 字符方面相同。
QString::toUtf8()
返回QByteArray
;并且QTextStream::operator<<(const QByteArray&)
很可能原封不动地写入这些字节。(这在文档中甚至没有提到。
因此,Hello, World!
仅包含 ASCII 表中可用的字符(代码<127)。甚至,如果OP视图工具支持/期望例如Windows 1252,它也不会注意到这一点。(我假设无法检测/处理 UTF-16 或 UTF-32 的工具可能也无法检测/处理 UTF-8。
顺便说一句,要找出"???????"
实际上是什么编码,可以使用十六进制视图工具查看myfile.csv
。由于输入是已知的,编码可能可以从输出中推断出来。(例如,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如何产生"???????"
以及它实际包含的内容会很有趣。
- 如何使用curlpp通过POST方法上传文件和json数据
- 一种在C++中读取TXT配置文件的简单方法
- 在 cpp 文件中隐藏采用模板参数引用的方法
- 在C++中包含原型文件的正确方法是什么?
- 通过比较C++中的行在 txt 文件中搜索的最简单方法是什么?
- 不带预处理器的调用方法/文件的文件名/行号
- 引用文件的适当方法是什么?
- 在文件中写入而不是在 c++ 中使用 "<<" 的替代方法?
- 查找定义我的 C/C++ 函数/宏的文件比'grep'更简单的方法
- 读取大文件(>2GB)(文本文件包含以太网数据)并通过不同参数随机访问数据的最佳方法是什么?
- 在C++中创建文件夹选取器对话框的最简单方法是什么?
- C++:std::ofstream 方法 open() 在第二次迭代时擦除打开的 ifstream 文件
- 如何使用 C/C++ 和 system() 系统调用以外的其他方法在 Linux 中获取文件功能?
- 创建进行生产构建并创建调试信息的C++生成文件的最佳方法?
- 是否有正确的方法对生成文件中的对象文件使用模板命令?(C++)
- 将位字符串转储到二进制文件的最佳方法是什么
- 在目录中查找所有.cpp.h文件(include,src等)的传统方法
- 是在DEX文件方法计数中计数的本机C 方法
- C++更新 txt 文件方法
- h头文件方法混乱