Wie ein std :: fstream (ofstream oder ifstream) mit einem Unicode-Dateinamen öffnen?
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?
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 char
s 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_t
s werden, oder es hat _T()
Makro haben oder Präfix L
before 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()));