Создайте файл UTF-8 в Qt
Я пытаюсь создать кодированный файл UTF-8 в Qt.
#include <QtCore>
int main()
{
QString unicodeString = "Some Unicode string";
QFile fileOut("D:\\Temp\\qt_unicode.txt");
if (!fileOut.open(QIODevice::WriteOnly | QIODevice::Text))
{
return -1;
}
QTextStream streamFileOut(&fileOut);
streamFileOut.setCodec("UTF-8");
streamFileOut << unicodeString;
streamFileOut.flush();
fileOut.close();
return 0;
}
Я думал, что когда QString по умолчанию является Unicode, и когда я устанавливаю кодек выходного потока в UTF-8, мой файл будет UTF-8. Но это не так, это ANSI.
Что я делаю неправильно? Что-то не так с моими струнами? Можете ли вы исправить мой код для создания файла UTF-8?
Следующим шагом для меня будет чтение файла ANSI и сохранение его как файла UTF-8, поэтому мне придется выполнить преобразование для каждой строки чтения, но теперь я хочу начать с файла.
Спасибо.
Ответы
Ответ 1
Ваш код абсолютно правильный. Единственная часть, которая выглядит для меня подозрительной, такова:
QString unicodeString = "Some Unicode string";
Вы понимаете, что вы не можете просто ввести строку Юникода в кавычки, не так ли? По умолчанию QString использует Latin1, поэтому, если речь идет только о акцентированных символах, вы, вероятно, все в порядке, но лучше, чтобы ваш источник закодирован в UTF-8 и сделал это:
QString unicodeString = QString::fromUtf8("Some Unicode string");
Это будет работать на любом воображаемом языке. Использование QObject:: trUtf8() еще лучше, поскольку оно дает вам много возможностей i18n.
Edit
Хотя верно, что вы создаете правильный файл UTF-8, если вы хотите, чтобы Notepad распознал ваш файл как UTF-8, это другая история. Вам нужно разместить там спецификацию. Это можно сделать либо в другом ответе, либо в другом виде:
streamFileOut.setGenerateByteOrderMark(true);
Ответ 2
Мой опыт создания txt-кодирования UTF-8 без спецификации по QT как:
file.open(QIODevice::WriteOnly | QIODevice::Text);
QTextStream out(&file);
out.setCodec("UTF-8"); // ...
vcfline = ctn; //assign some utf-8 characters
out.setGenerateByteOrderMark(false);
out << vcfline; //.....
file.close();
И файл будет кодировать UTF-8 без спецификации.
Ответ 3
Не забывайте, что UTF-8 кодировка будет кодировать символы ASCII в виде одного байта. Только специальные или акцентированные символы будут закодированы с большим количеством байтов (от 2 до 6 байтов).
Это означает, что если у вас есть символы ASCII (что соответствует вашему unicodeString
), файл будет содержать только 8 байтов. Таким образом, вы получаете обратную совместимость с ASCII:
UTF-8 может представлять каждый символ в наборе символов Unicode, но в отличие от них обладает преимуществами обратной совместимости с ASCII
Чтобы проверить, работает ли ваш код, вы должны указать, например, некоторые подчеркнутые символы в вашем юникоде.
Я проверил ваш код с подчеркнутыми символами, и он отлично работает.
Если вы хотите иметь спецификацию в начале вашего файла, вы можете начать с добавления символа спецификации (QChar(QChar::ByteOrderMark)
).