2011-01-24 10 views
18

Próbuję utworzyć zakodowany plik UTF-8 w Qt.Utwórz plik UTF-8 w 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; 
} 

myślałem kiedy QString jest domyślnie Unicode i kiedy ustawić kodek strumienia wyjściowego na UTF-8, że mój plik będzie UTF-8. Ale tak nie jest, to ANSI. Co mam zrobić źle? Czy coś jest nie tak z moimi strunami? Czy możesz poprawić mój kod, aby utworzyć plik UTF-8? Następnym krokiem dla mnie będzie odczytanie pliku ANSI i zapisanie go jako pliku UTF-8, więc będę musiał wykonać konwersję na każdym ciągu odczytu, ale teraz chcę zacząć od pliku. Dziękuję.

+1

Powinieneś przekonwertować ciąg literału na ciąg znaków za pomocą QString :: fromUtf8(). Ponadto niektóre kompilatory mają problemy z kodowaniem innym niż ascii w plikach źródłowych (MSVC).Więc może również spróbuj, jeśli działa przy wprowadzaniu łańcucha przez np. QInputDialog. Proponuję również zdefiniować QT_NO_CAST_FROM_ASCII i QT_NO_CAST_TO_ASCII podczas napotykania takich problemów. Wyłącza niejawne konwersje, dzięki czemu jest bardziej przejrzyste, co się dzieje. –

+0

http://stackoverflow.com/questions/29485602/qt-convert-unicode-entites – trante

Odpowiedz

16

Twój kod jest całkowicie poprawny. Jedynym elementem, który wygląda podejrzanie mi to:

QString unicodeString = "Some Unicode string"; 

Zdajesz sobie sprawę, że nie można po prostu umieścić ciąg Unicode w cudzysłowie, prawda? QString domyślnie używa Latin1, więc jeśli tylko o akcentowane znaki, prawdopodobnie jesteś w porządku, ale lepiej mieć źródło zakodowane w UTF-8 i to zrobić:

QString unicodeString = QString::fromUtf8("Some Unicode string"); 

To będzie działać na każdym języku można sobie wyobrazić. Używanie QObject :: trUtf8() jest jeszcze lepsze, ponieważ zapewnia wiele możliwości i18n.

Edit

Choć to prawda, że ​​można wygenerować poprawny plik UTF-8, jeśli chcesz Notatnik rozpoznać plik jako UTF-8, to już zupełnie inna historia. Musisz umieścić tam BOM. Można to zrobić albo jak sugeruje inną odpowiedź, czy tu jest inny sposób:

streamFileOut.setGenerateByteOrderMark(true); 
+1

Nie polecam utrzymywania źródła C++ w UTF-8 :) –

+1

@Piotr, dlaczego? UTF-8 (bez BOM) to kodowanie, które jest doskonale zgodne z US-ASCII i obsługuje dowolny język. Jak inaczej używać literałów znaków w niektórych językach ojczystych, bez uciekania się do QTextStream :: setCodecForCStrings(), co może prowadzić do wielu problemów? –

+0

@Sergey. Muszę się zgodzić z Piotrem. Problem polega na tym, że w pliku źródłowym znajdują się literały inne niż ASCII, a do tego, aby preportory i kompilatory próbowały ich nie zamykać, zależą od nich. Nie mam wątpliwości, że większość nowoczesnych narzędzi poradzi sobie z tym. Ale dlaczego pozostawić to przypadkowi? –

5

Nie zapominaj, że kodowanie UTF-8 będzie kodować znaki ASCII jako jeden bajt. Tylko specjalne lub zaakcentowane znaki będą kodowane z większą liczbą bajtów (od 2 do 6 bajtów).

To oznacza tak długo, jak masz znaki ASCII (co jest w przypadku Twojego unicodeString), plik będzie zawierał tylko 8 bajtów. W ten sposób można uzyskać wsteczną kompatybilność z ASCII:

UTF-8 może reprezentować każdy znak w zestawie znaków Unicode, ale w przeciwieństwie do nich, posiada zalety bycia wstecznie kompatybilny z ASCII

aby sprawdzić jeśli twój kod działa, powinieneś umieścić na przykład jakieś akcentowane znaki w twoim unicode.

Przetestowałem Twój kod z wyróżnionymi znakami i wszystko działa poprawnie.

Jeśli chcesz mieć BOM na początku pliku, możesz zacząć od dodania znaku BOM (QChar(QChar::ByteOrderMark)).

+0

Dziękuję, Jerome, pomógł mi z BOM. Plik był naprawdę w porządku, ale brakowało BOM. Używam metody Siergieja, by dodać ją do strumienia, ale twoja pomoc jest bardzo doceniana. –

7

Moje doświadczenie do tworzenia txt kodowanie UTF-8 bez BOM przez QT jako:

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(); 

a plik zostanie kodowanie UTF-8 bez LM.

+0

Jeśli czytasz z pliku, ustaw kodek dla strumieni plików wejściowych i wyjściowych. –