直接上代码,有一部分是GPT直接生成的:
#include <QCoreApplication>
#include <QFile>
#include <QTextCodec>
#include <QDebug>
// 判断是否为UTF-8编码
bool isUtf8(const QByteArray &data) {
int i = 0;
while (i < data.size()) {
if ((data[i] & 0x80) == 0) { // 0xxxxxxx
i++;
continue;
}
if ((data[i] & 0xE0) == 0xC0) { // 110xxxxx 10xxxxxx
if (i + 1 >= data.size() || (data[i + 1] & 0xC0) != 0x80)
return false;
i += 2;
continue;
}
if ((data[i] & 0xF0) == 0xE0) { // 1110xxxx 10xxxxxx 10xxxxxx
if (i + 2 >= data.size() || (data[i + 1] & 0xC0) != 0x80 || (data[i + 2] & 0xC0) != 0x80)
return false;
i += 3;
continue;
}
if ((data[i] & 0xF8) == 0xF0) { // 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx
if (i + 3 >= data.size() || (data[i + 1] & 0xC0) != 0x80 || (data[i + 2] & 0xC0) != 0x80 || (data[i + 3] & 0xC0) != 0x80)
return false;
i += 4;
continue;
}
return false;
}
return true;
}
// 判断是否为GB2312编码
bool isGb2312(const QByteArray &data) {
QTextCodec *codec = QTextCodec::codecForName("GB2312");
if (!codec)
return false;
QString decodedString = codec->toUnicode(data);
QByteArray encodedData = codec->fromUnicode(decodedString);
return data == encodedData;
}
// 检测文件编码
QString detectEncoding(const QString &filePath) {
QFile file(filePath);
if (!file.open(QIODevice::ReadOnly)) {
qWarning() << "Failed to open file:" << filePath;
return "Unknown";
}
QByteArray data = file.readAll();
if (isUtf8(data)) {
return "UTF-8";
} else if (isGb2312(data)) {
return "GB2312";
} else {
return "Unknown";
}
}
int main(int argc, char *argv[]) {
QCoreApplication a(argc, argv);
QString filePath = "path/to/your/file.txt";
QString encoding = detectEncoding(filePath);
qDebug() << "File encoding:" << encoding;
return a.exec();
}
代码解释
- isUtf8函数:通过检查字节模式来判断数据是否符合UTF-8编码的格式。
- isGb2312函数:使用Qt的
QTextCodec
来尝试将数据解码为GB2312,再编码回原始数据进行比较。如果一致,说明数据是GB2312编码。 - detectEncoding函数:读取文件内容,并使用
isUtf8
和isGb2312
函数来判断文件的编码格式。 - main函数:创建Qt应用程序实例,调用
detectEncoding
函数并输出文件的编码格式。
注意事项
- 这种方法并不是百分百准确,因为某些字节序列在不同编码下可能都是合法的。因此,检测结果仅供参考。
- 复杂的字符编码检测通常需要更复杂的算法或使用专门的库,如ICU(International Components for Unicode)。
- 对于大文件,可以只读取文件的前几KB进行检测,以提高性能。