系列文章目录
前言
使用Qt中的QFile类读取ANSI编码格式的文本文件,并在QTextEdit控件中显示乱码,这可能是由于编码问题导致的。QFile类默认使用系统的本地编码来读取文件,而ANSI编码通常与系统的本地编码不同。
为了正确地读取ANSI编码的文本文件并在QTextEdit控件中显示,你可以使用QTextCodec类来指定正确的编码。以下是一个示例代码片段,演示了如何读取ANSI编码的文本文件并在QTextEdit控件中显示正确的文本:
#include <QApplication>
#include <QFile>
#include <QTextStream>
#include <QTextCodec>
#include <QTextEdit>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
// 创建QTextEdit控件
QTextEdit textEdit;
// 读取ANSI编码的文本文件
QFile file("path_to_your_file.txt");
if (file.open(QIODevice::ReadOnly | QIODevice::Text))
{
// 使用ANSI编码创建QTextCodec对象
QTextCodec *codec = QTextCodec::codecForName("Windows-1252");
// 使用指定的编码创建QTextStream对象
QTextStream stream(&file);
stream.setCodec(codec);
// 读取文本文件内容
QString content = stream.readAll();
// 在QTextEdit控件中显示文本
textEdit.setPlainText(content);
// 关闭文件
file.close();
}
// 显示窗口
textEdit.show();
return app.exec();
}
一、依然无法解决乱码问题
使用了Windows-1252编码(也称为ANSI编码)来创建了一个QTextCodec对象,并将其应用于QTextStream,以便正确解码文件内容。然后,我们将解码后的文本内容设置为QTextEdit控件的文本。使用utf8依然无法解决乱码问题,
void ProjectWin::readParaFile(QString filePath)
{
m_paraText->clear();
if (!m_paraText) {
qDebug() << "m_paraText is null!";
return;
}
QString txtFile = filePath.left(filePath.size() -3);
txtFile += "txt";
QFile file(filePath);
if(!file.open(QIODevice::ReadOnly)) {
qDebug() << file.errorString();
}
// QByteArray fileData = file.readAll(); // 一次性读取整个文件内容
// QString decodedText = QTextCodec::codecForName("UTF-8")->toUnicode(fileData); // 使用UTF-8解码
// m_paraText->setPlainText(decodedText); // 设置文本内容
QTextStream in(&file);
in.setCodec("UTF-8"); // 设置编码为UTF-8
// in.setCodec("GBK"); // 设置编码为GB18030
QString chineseText;
// QTextCodec* codec = QTextCodec::codecForName("UTF-8"); // 指定正确的文本编码
while(!in.atEnd()) {
QString line = in.readLine();
// QByteArray utf8Data = line.toUtf8();
// qDebug() << utf8Data.data();
// line = line.trimmed(); //去掉2端字符串空格
// emit appendText(line); // 使用信号来添加文本
if(line.contains(u8"任务代号:", Qt::CaseSensitive))
{
int pos = line.lastIndexOf(":");
QString taskNum = line.right(line.size() - pos - 2);
taskNum = taskNum.trimmed();
m_taskNumSet.insert(taskNum);
// break;
}
// m_paraText->setFont(QFont("Microsoft YaHei"));
// m_paraText->setFont(QFont("Microsoft YaHei")); // 使用"Microsoft YaHei"字体
m_paraText->append(line); // 添加到QTextEdit控件中
}
file.close();
}
二、解决办法
1.方法一:使用QString的fromLocal8Bit()函数
void ProjectWin::readParaFile(QString filePath)
{
m_paraText->clear();
if (!m_paraText) {
qDebug() << "m_paraText is null!";
return;
}
QString txtFile = filePath.left(filePath.size() -3);
txtFile += "txt";
filePath = "E:/work/ImageManageSys/utf8/0000_051623_162252_05_004_00001_00008_00.txt";
QFile file(filePath);
if(file.open(QIODevice::ReadOnly)) {
// qDebug() << file.errorString();
QTextCodec::setCodecForLocale(QTextCodec::codecForName("gb2312"));//中文转码声明
QString temStr;
while(!file.atEnd())
{
QByteArray arr = file.readAll();
arr.replace(0x0B,0x0D);
temStr = QString::fromLocal8Bit(arr, arr.length());//Window下的QByteArray转QString
m_paraText->append(temStr);
}
//读取任务号
while (!file.atEnd())
{
QString line = file.readLine();
if(line.contains(u8"任务代号:", Qt::CaseSensitive))
{
int pos = line.lastIndexOf(":");
QString taskNum = line.right(line.size() - pos - 2);
taskNum = taskNum.trimmed();
m_taskNumSet.insert(taskNum);
break;
}
}
}
file.close();
}
这种方式读取ansi编码格式的txt文件可以正常显示,但是如果读取utf-8格式的txt文件反而是乱码,切记!切记!切记!重要的事说三遍。
2.读取utf-8编码格式的文件
void ProjectWin::readParaFile(QString filePath)
{
m_paraText->clear();
if (!m_paraText) {
qDebug() << "m_paraText is null!";
return;
}
QString txtFile = filePath.left(filePath.size() -3);
txtFile += "txt";
QFile file(filePath);
if(!file.open(QIODevice::ReadOnly)) {
qDebug() << file.errorString();
}
// QByteArray fileData = file.readAll(); // 一次性读取整个文件内容
// QString decodedText = QTextCodec::codecForName("UTF-8")->toUnicode(fileData); // 使用UTF-8解码
// m_paraText->setPlainText(decodedText); // 设置文本内容
QTextStream in(&file);
in.setCodec("UTF-8"); // 设置编码为UTF-8
// in.setCodec("GBK"); // 设置编码为GB18030
QString chineseText;
// QTextCodec* codec = QTextCodec::codecForName("UTF-8"); // 指定正确的文本编码
while(!in.atEnd()) {
QString line = in.readLine();
// QByteArray utf8Data = line.toUtf8();
// qDebug() << utf8Data.data();
// line = line.trimmed(); //去掉2端字符串空格
// emit appendText(line); // 使用信号来添加文本
if(line.contains(u8"任务代号:", Qt::CaseSensitive))
{
int pos = line.lastIndexOf(":");
QString taskNum = line.right(line.size() - pos - 2);
taskNum = taskNum.trimmed();
m_taskNumSet.insert(taskNum);
// break;
}
// m_paraText->setFont(QFont("Microsoft YaHei"));
// m_paraText->setFont(QFont("Microsoft YaHei")); // 使用"Microsoft YaHei"字体
m_paraText->append(line); // 添加到QTextEdit控件中
}
file.close();
}
总结
在Qt中,QFile类本身并不提供直接获取文件编码格式的方法。文件编码是文件内容的属性,QFile只提供了对文件的读取和写入功能。要获取文件的编码格式,你可以使用其他的库或方法来分析文件内容并推断出编码格式。
一种常用的方法是使用第三方库如uchardet或libmagic来检测文件的编码。这些库可以通过分析文件内容的特征来猜测其可能的编码格式。你可以将文件内容读取到内存中,并使用这些库来进行编码检测。
以下是一个使用uchardet库来检测文件编码的示例:
在Qt项目中集成uchardet库,可以使用CMake或手动编译该库。
在Qt项目的代码中引入uchardet的头文件和链接库。
使用QFile读取文件内容,并将其传递给uchardet来检测编码格式。
#include <uchardet/uchardet.h>
QString detectFileEncoding(const QString& filePath)
{
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file:" << file.errorString();
return QString();
}
QByteArray data = file.readAll();
uchardet_t ud = uchardet_new();
uchardet_handle_data(ud, data.constData(), data.size());
uchardet_data_end(ud);
const char* encoding = uchardet_get_charset(ud);
QString detectedEncoding = QString::fromLatin1(encoding);
uchardet_delete(ud);
file.close();
return detectedEncoding;
}
void ProjectWin::readFileAndDetectEncoding(const QString& filePath)
{
QString detectedEncoding = detectFileEncoding(filePath);
qDebug() << "Detected Encoding:" << detectedEncoding;
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
qDebug() << "Failed to open file:" << file.errorString();
return;
}
QTextStream in(&file);
in.setCodec(detectedEncoding.toUtf8()); // 设置检测到的编码
QString content = in.readAll();
file.close();
// 处理读取到的文件内容...
}
上述代码中的detectFileEncoding()函数使用uchardet库来检测文件的编码格式,并返回检测到的编码字符串。然后,在readFileAndDetectEncoding()函数中,使用检测到的编码来设置QTextStream的编码,以正确读取文件内容。
请注意,uchardet是一个独立的第三方库,并不随Qt自带。你需要在项目中引入并正确配置该库的构建和链接。
另外,需要注意的是,自动检测编码并不总是100%准确,特别是对于一些特殊或混合编码的文件,可能会有误判。因此,最好还是能够事先知道文件的准确编码格式,或者提前约定好文件的编码方式。