Wie ein std :: fstream (ofstream oder ifstream) mit einem Unicode-Dateinamen öffnen?

StackOverflow https://stackoverflow.com/questions/821873

  •  03-07-2019
  •  | 
  •  

Frage

Sie würden nicht etwas so Grundlegendes wie das Öffnen einer Datei vorstellen, dass die C ++ Standardbibliothek für eine Windows-Anwendung war heikel ... aber es scheint zu sein. Durch die Unicode hier meine ich UTF-8, aber ich kann auf UTF-16 oder was auch immer konvertieren, wird der Punkt eine ofstream Instanz von einem Unicode-Dateinamen zu bekommen. Bevor ich meine eigene Lösung zerhacken, gibt es eine hier bevorzugte Route? Vor allem einer Cross-Plattform ein?

War es hilfreich?

Lösung

Die C ++ Standard-Bibliothek ist nicht Unicode-aware. char und wchar_t sind Unicode-Codierungen werden nicht benötigt.

Unter Windows ist wchar_t UTF-16, aber es gibt keine direkte Unterstützung für UTF-8 Dateinamen in der Standard-Bibliothek (der char Datentyp Unicode ist nicht auf Windows)

Mit MSVC (und damit der Microsoft STL), ein Konstruktor für Filestreams vorgesehen ist, die einen const wchar_t* Dateinamen nimmt, so dass Sie den Stream erstellen:

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

Allerdings ist diese Überlastung nicht durch den C ++ 11-Standard spezifiziert (es garantiert nur das Vorhandensein der char basierten Version). Es ist auch nicht vorhanden auf alternative STL-Implementierungen wie GCC libstdc ++ für MinGW (-w64), ab Version g ++ 4.8.x.

Beachten Sie, dass wie char unter Windows ist nicht UTF8, auf andere OS'es wchar_t nicht UTF16 sein kann. Also insgesamt, dann ist dies wahrscheinlich nicht tragbar sein. Das Öffnen eines Stream ein wchar_t Dateiname angegeben wird, gemäß dem Standard nicht definiert ist, und die Angabe der Dateiname in chars schwierig sein kann, da die Codierung durch char zwischen OS'es variiert verwendet.

Andere Tipps

Die aktuellen Versionen von Visual C ++ std :: basic_fstream haben eine open() Methode, die einen wchar_t nehmen * gemäß http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx .

Da C ++ 17, gibt es eine plattformübergreifende Art und Weise eine std :: fstream mit Unicode-Dateinamen zu öffnen, mit der std :: filesystem :: path Überlastung. Bis C ++ 20, können Sie einen Pfad aus einem UTF-8-String mit std :: filesystem :: u8path . Beispiel:

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

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

Mit std::wofstream, std::wifstream und std::wfstream. Sie akzeptieren Unicode-Dateinamen. Dateiname hat wstring, Array von wchar_ts werden, oder es hat _T() Makro haben oder Präfix Lbefore der Text.

Hier finden Sie aktuelle 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;
}

Wenn Sie mit Qt gemischt mit std::ifstream:

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top