Wie zu Lesen die UTF-8-kodierte text-Datei mit std::ifstream?
Ich habe eine harte Zeit, die zum Parsen einer xml-Datei.
Speichern der Datei mit der Codierung UTF-8.
Normalen ASCII richtig gelesen, aber die koreanischen Zeichen nicht.
Also habe ich ein einfaches Programm zum Lesen einer UTF-8-Textdatei und drucken Sie den Inhalt.
Text-Datei(test.txt)
ABC가나다
- Test-Programm
#include <fstream>
#include <iostream>
#include <string>
#include <iterator>
#include <streambuf>
const char* hex(char c) {
const char REF[] = "0123456789ABCDEF";
static char output[3] = "XX";
output[0] = REF[0x0f & c>>4];
output[1] = REF[0x0f & c];
return output;
}
int main() {
std::cout << "File(ifstream) : ";
std::ifstream file("test.txt");
std::string buffer((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
for (auto c : buffer) {
std::cout << hex(c)<< " ";
}
std::cout << std::endl;
std::cout << buffer << std::endl;
//String literal
std::string str = "ABC가나다";
std::cout << "String literal : ";
for (auto c : str) {
std::cout << hex(c) << " ";
}
std::cout << std::endl;
std::cout << str << std::endl;
return 0;
}
Ausgabe
File(ifstream) : 41 42 43 EA B0 80 EB 82 98 EB 8B A4
ABC媛?섎떎
String literal : 41 42 43 B0 A1 B3 AA B4 D9
ABC가나다
Die Ausgabe sagt, dass die Zeichen codiert sind, anders als im string-literal " und " Datei.
So weit ich weiß, in c++ char
strings werden in UTF-8 kodiert, so können wir sehen, wie Sie durch printf
oder cout
. Also die bytes, die sollten gleich sein, aber Sie waren anders eigentlich...
Gibt es eine Möglichkeit zum Lesen von UTF-8 text-Datei mit std::ifstream
?
Mir gelingt, parse xml-Datei mit std::wifstream
folgenden dieser Artikel.
Aber die meisten Bibliotheken, die ich verwende sind die Unterstützung nur const char*
string, also ich bin auf der Suche nach einem anderen Weg, um std::ifstream
.
- Und auch das habe ich gelesen dieser Artikel sagen, die nicht mit wchar_t
. Behandlung von char
string als multi-Byte-Zeichen ist ausreichend.
- Sie sollten
imbue()
eine UTF-8-Gebietsschema in derstd::ifstream
vor dem Einlesen der Datei Daten. Sie müssen auchimbue()
eine UTF-8-Gebietsschema instd::cout
, und/oder legen Sie Ihre terminal-charset auf UTF-8. Ihreifstream
Ausgabe ist korrekt für UTF-8 (UTF-8-codierten formABC가나다
wirklich ist 12 bytes). Ihre string-literal Beispiel produziert nicht die richtige Leistung, denn es unterliegt den Zeichensatz auswählen, der Sie gerettet, Ihren source-code-Datei, sowie der Zeichensatz Ihres Terminals, von denen keines sind mit UTF-8. - Dies ist jedoch nicht sinnvoll. Wenn eine Datei ist in UTF8 kodiert, und wenn Sie ihn Lesen wollen, in 8bit-Zeichen (
std::string
von `char) als UTF8, Sie müssen nur Lesen Sie die Zeichen ohne Konvertierung. Was Sie genau zu erreichen versucht? - Wenn Sie auf Windows müssen Sie möglicherweise öffnen Sie die Dateien im Binär-Modus, um zu verhindern, dass bestimmte Zeichen Konvertierungen. Ich hatte noch nie ein problem beim Lesen
UTF-8
mit Datei-streams. - MSVC-Runtime unterstützt keine Unicode-locales, so dass der einzige Weg, um UTF-8-locale-Objekt zu verleihen stream mit ist durch die Verwendung von Boost.Gebietsschema, das ist viel zu viel für solch einfache Aufgabe.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Codierung "ABC가나다" UTF-8 sollte Ihnen
also der Inhalt der Datei korrekt ist. Die Probleme mit deiner Quelle-Datei-Codierung. Sie sind nicht zulässig für die Verwendung von nicht-ascii-Zeichen in string-literalen mögen, sollten Sie die Präfix mit u8 zu bekommen UTF-8-Literale:
Ich an dieser Stelle davon ausgegangen, dass Sie Windows, sonst würdest du nicht irgendwelche Probleme mit Codierungen. Müssen Sie Ihr Terminal-Zeichensatz zu UTF-8:
Was ist passiert in deinem Fall ist, dass Sie das Lesen von UTF-8-text aus einer Datei in einen string, dann drucken Sie es auf nicht-unicode-terminal ist nicht in der Lage es zu zeigen, wie Sie es erwarten. Wenn Sie drucken Ihre string-literal, das Sie drucken nicht-unicode-Sequenz, aber diese Sequenzen enconding entspricht Ihr terminal-encoding, so dass Sie sehen können, was Sie erwartet.
PS: ich habe https://mothereff.in/utf-8 um UTF-8 represenation des Strings in hex.