Frage an unicode, utf-8, c++, windows, fstream – fstream :: open () Unicode- oder Nicht-ASCII-Zeichen funktionieren unter Windows nicht (mit std :: ios :: out)

3

In einem C ++ - Projekt möchte ich eine Datei öffnen (fstream::open()) (was ein großes Problem zu sein scheint). Der Windows-Build meines Programms schlägt kläglich fehl.

Datei "ä" (UTF-8 0xC3 0xA4)

<code>std::string s = ...;
//Convert s
std::fstream f;
f.open(s.c_str(), std::ios::binary | std::ios::in); //Works (f.is_open() == true)
f.close();
f.open(s.c_str(), std::ios::binary | std::ios::in | std::ios::out); //Doesn't work
</code>

Die Saites wird UTF-8-codiert, dann aber von UTF-8 nach Latin1 (0xE4) konvertiert. Ich benutze also QtQString::fromUtf8(s.c_str()).toLocal8Bit().constData().

Warum kann ich die Datei zum Lesen öffnen, aber nicht zum Schreiben?

Datei "è" (UTF-8 0xD0 0xB8)

Gleicher Code, funktioniert überhaupt nicht.

Es scheint, dass dieses Zeichen nicht in den Windows-1252-Zeichensatz passt. Wie kann ich einen solchen Fstream öffnen (ich verwende MSVC also nicht)?Neinfstream::open(const wchar_t*, ios_base::openmode))?

Lange Antwort auf kurzen Kommentar: sieheutf8everywhere.org darüber, wie man es richtig macht. Pavel Radzivilovsky
Welchen Compiler und welche C-Bibliothek verwenden Sie? Wenn Sie beispielsweise MinGW verwenden, können Sie weiterhin Funktionen des MS CRT verwenden, z_wfopen. Wenn Sie eine andere C-Laufzeitumgebung verwenden (z. B. die libc von Cygwin GCC), sind Sie der Unicode-Unterstützung dieser Laufzeitbibliothek ausgeliefert. Adam Rosenfield
@Adam Rosenfield Ich benutze mingw32-g ++ - 4.6.2. _wfopen () gibt einen FILE * -Zeiger zurück. Wie öffne ich ein Fstream-Objekt auf diese Weise? basic6
Ich denke, Dateinamen in Windows müssen UTF-16-codiert sein, und Sie müssen die speziellen Windows-Dateibehandlungsfunktionen verwenden (_wfopenusw.), um über ihren langen Namen auf Dateien zuzugreifen. Alternativ können Sie den Kurznamen verwenden. Kerrek SB

Deine Antwort

2   die antwort
3

In Microsoft-Implementierungen von STL gibt es eine nicht standardmäßige Erweiterung (Überladung), um die Unicode-Unterstützung für UTF-16-codierte Zeichenfolgen zu ermöglichen.

Übergeben Sie einfach UTF-16-codierten std :: wstring an fstream :: open (). Nur so kann es mit fstream funktionieren.

Weitere Informationen darüber, wie ich Unicode unter Windows am einfachsten unterstütze, finden Sie hier:http://utf8everywhere.org/

@ basic6: lies bitte dieKonvertierungsfunktionen Sektion. AFAIK die nowide Bibliothek sollte auch auf MinGW funktionieren. ybungalobill
Das ist wahrscheinlich die passende Lösung, aber AFAIK diese Überladung ist nur mit MSVC verfügbar, nicht mit MinGW ("keine passende Funktion für Anruf an ..."). Und ich verwende den Microsoft-Compiler nicht, weil ich den Code, an dem ich gerade arbeite, nicht auf Microsoft C ++ portiert habe (mit anderen Worten, der Code wird nicht kompiliert und ich habe mich noch nicht darum gekümmert, herauszufinden, warum). basic6
3

Mit den Standard-APIs (z. B. std :: fstream) unter Windows können Sie eine Datei nur öffnen, wenn der Dateiname mit der aktuell eingestellten "ANSI-Codepage" (CP_ACP) codiert werden kann.

Dies bedeutet, dass es Dateien geben kann, die mit diesen APIs unter Windows einfach nicht geöffnet werden können. Wenn Microsoft keine Unterstützung für das Festlegen von CP_ACP auf CP_UTF8 implementiert, kann dies nicht mit der CRT- oder C ++ - Standardbibliotheksimplementierung von Microsoft erfolgen.

(Windows hat eine Funktion namens "kurze" Dateinamen, bei der bei Aktivierung jede Datei auf dem Laufwerk einen ASCII-Dateinamen hatte, der über Standard-APIs verwendet werden kann. Diese Funktion wird jedoch nicht mehr unterstützt, sodass sie keine praktikable Lösung darstellt.)

Verwandte Fragen