it-swarm.com.de

Wie öffnet man einen std :: fstream (ofstream oder ifstream) mit einem Unicode-Dateinamen?

Sie können sich nicht vorstellen, dass etwas so grundlegendes wie das Öffnen einer Datei mit der C++ - Standardbibliothek für eine Windows-Anwendung schwierig ist ... aber es scheint so zu sein. Mit Unicode meine ich UTF-8, aber ich kann in UTF-16 oder was auch immer konvertieren. Der Punkt ist das Abrufen einer Ofstream-Instanz von einem Unicode-Dateinamen. Gibt es hier eine bevorzugte Route, bevor ich meine eigene Lösung hacke? Vor allem eine plattformübergreifende?

45

Die C++ - Standardbibliothek ist nicht Unicode-fähig. char und wchar_t müssen keine Unicode-Kodierungen sein.

Unter Windows ist wchar_t UTF-16, aber UTF-8-Dateinamen werden in der Standardbibliothek nicht direkt unterstützt (der Datentyp char ist unter Windows kein Unicode).

Mit MSVC (und damit der Microsoft STL) wird ein Konstruktor für Dateistreams bereitgestellt, der einen const wchar_t*-Dateinamen benötigt, sodass Sie den Stream wie folgt erstellen können:

wchar_t const name[] = L"filename.txt";
std::fstream file(name);

Diese Überladung wird jedoch nicht vom C++ 11-Standard angegeben (sie garantiert nur das Vorhandensein der auf char basierenden Version). Es ist auch nicht in alternativen STL-Implementierungen wie GCCs libstdc ++ für MinGW (-w64) ab Version g ++ 4.8.x vorhanden.

Beachten Sie, dass genau wie char unter Windows nicht UTF8 ist. In anderen Betriebssystemen ist wchar_t möglicherweise nicht UTF16. Insgesamt dürfte dies also nicht portabel sein. Das Öffnen eines Streams mit einem wchar_t-Dateinamen ist nicht gemäß dem Standard definiert. Die Angabe des Dateinamens in chars kann schwierig sein, da die von char verwendete Codierung je nach Betriebssystem unterschiedlich ist.

53
jalf

Die aktuellen Versionen von Visual C++, std :: basic_fstream, verfügen über eine open()-Methode, die ein wchar_t * gemäß http://msdn.Microsoft.com/en-us/library/4dx08bh4.aspx verwendet. 

3
John Downey

Verwenden Sie std::wofstream, std::wifstream und std::wfstream. Sie akzeptieren den Unicode-Dateinamen. Der Dateiname muss wstring sein, ein Array von wchar_ts, oder er muss über das _T()-Makro oder das Präfix L vor dem Text verfügen.

2
Brackets

Werfen Sie einen Blick auf Boost.Nowide :

#include <boost/nowide/fstream.hpp>
#include <boost/nowide/cout.hpp>
using boost::nowide::ifstream;
using boost::nowide::cout;

// #include <fstream>
// #include <iostream>
// using std::ifstream;
// using std::cout;

#include <string>

int main() {
    ifstream f("UTF-8 (e.g. ß).txt");
    std::string line;
    std::getline(f, line);
    cout << "UTF-8 content: " << line;
}
1
jhasse

Seit C++ 17 gibt es eine plattformübergreifende Möglichkeit, std :: fstream mit einem Unicode-Dateinamen mithilfe von std :: filesystem :: path overload zu öffnen. Bis C++ 20 können Sie einen Pfad aus einer UTF-8-Zeichenfolge mit std :: filesystem :: u8path erstellen. Beispiel:

std::ofstream out(std::filesystem::u8path(u8"こんにちは"));
out << "hello";

Nach C++ 20 können Sie einen Pfad erstellen, indem Sie UTF-8 an den Konstruktor übergeben: std::filesystem::path(u8"こんにちは") (u8path wird nicht mehr verwendet).

1
Nikolai

Wenn Sie Qt mit std::ifstream gemischt verwenden:

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
1