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

Lesezeit: 6 Minuten

Wie offne ich einen stdfstream ofstream oder ifstream mit einem
Andreas Beatty

Sie würden sich nicht vorstellen, dass etwas so Einfaches wie das Öffnen einer Datei mit der C++-Standardbibliothek für eine Windows-Anwendung schwierig war … aber es scheint so zu sein. Mit Unicode meine ich hier UTF-8, aber ich kann in UTF-16 oder was auch immer konvertieren, der Punkt ist, eine Ofstream-Instanz von einem Unicode-Dateinamen zu bekommen. Bevor ich meine eigene Lösung hacke, gibt es hier eine bevorzugte Route? Vor allem plattformübergreifend?

  • Ich dies ist eine doppelte Frage. Sehen Sie, ob eine der Antworten dort helfen kann.

    – Yorgos Pagles

    4. Mai 2009 um 20:37 Uhr

  • Warum verwenden Sie keine Datentypen wie std::wofstream? Beachten Sie die w!

    – sergiol

    23. November 2016 um 18:53 Uhr

Wie offne ich einen stdfstream ofstream oder ifstream mit einem
jalf

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

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

Mit MSVC (und damit der Microsoft STL) wird ein Konstruktor für Filestreams bereitgestellt, der eine const wchar_t* Dateiname, sodass Sie den Stream erstellen können als:

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

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

Beachten Sie, dass genau wie char unter Windows ist nicht UTF8, unter anderen Betriebssystemen wchar_t darf nicht UTF16 sein. Insgesamt ist dies also wahrscheinlich nicht tragbar. Öffnen eines Streams gegeben a wchar_t filename ist nicht nach dem Standard definiert, und die Angabe des Dateinamens in chars kann schwierig sein, da die von char verwendete Kodierung zwischen den Betriebssystemen variiert.

  • Eine weitaus vollständigere und aktuellere Antwort, einschließlich der Vorgehensweise mit g++ sowie anderer Windows-API-Möglichkeiten usw., ist in einem neueren Thread verfügbar.

    – Prost und hth. – Alf

    31. Mai 2014 um 14:09 Uhr


  • @MichalM: nein. wchar_t ist natürlich nur ein 16-Bit breiter Zeichentyp, in dem alles gespeichert werden kann, was Sie möchten. Es kümmert sich nicht um Codierungen. Aber die Win32-APIs, die akzeptieren wchar_t Argumente erwarten, dass sie UTF-16-Daten enthalten. Die Windows-API verwendet UCS-2 seit Windows 2000 nicht mehr,

    – jalf

    13. November 2015 um 15:03 Uhr

  • @MichalM: Was ist ist (nicht was es nahe kommt, sondern was ist eigentlich gespeichert in einem wchar_t) ist ein UTF-16 Codeeinheit. Es ist nicht UCS-2, und obwohl es UCS-2 nahe kommt, ist es noch näher an einer UTF-16-Codeeinheit (denn das ist es tatsächlich ist). UTF-16 spezifiziert einen Codepunkt, der durch eine oder zwei Codeeinheiten dargestellt werden soll, wobei letztere als Ersatzpaar bezeichnet werden.

    – jalf

    18. November 2015 um 10:43 Uhr

  • Diese Antwort ist seit C++17 veraltet.

    – Nicolai

    23. Februar 2019 um 12:55 Uhr

  • wirklich? es ist ofc in minigw vorhanden, da minigw msvc copypaste ist

    – Алексей Неудачин

    2. August 2020 um 8:42 Uhr

1646640614 989 Wie offne ich einen stdfstream ofstream oder ifstream mit einem
Nikolai

Seit C++17 gibt es eine plattformübergreifende Möglichkeit, einen std::fstream mit einem Unicode-Dateinamen mithilfe der std::Dateisystem::Pfad Überlast. Beispiel:

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

  • Als ich dies unter Windows versuchte, hieß die erstellte Datei “ã“ã‚“ã«ã¡ã¯”. (Quelldatei gespeichert als UTF-8). Gibt es andere Schritte, die Sie ausführen müssen, damit dieses Beispiel einen korrekten Dateinamen erstellt?

    – Thomm

    11. Oktober 2020 um 20:41 Uhr

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

  • Wird dies letztendlich / theoretisch portabel sein?

    – Andreas Beatty

    4. Mai 2009 um 20:52 Uhr

  • Nicht alle Betriebssysteme und Dateisysteme unterstützen Unicode-Dateinamen, sodass sie nicht portierbar wären. Soweit ich weiß, sind wchar_t* open() und der Konstruktor auf fstream Microsoft-Erweiterungen, da NTFS Unicode-Dateinamen unterstützt.

    – John Downey

    4. Mai 2009 um 22:50 Uhr

  • oder besser gesagt, weil NTFS UTF16 verwendet, um Unicode-Dateinamen zu codieren. Linux unterstützt auch Unicode-Dateinamen, verwendet aber UTF8, sodass dort die reguläre char*-Version funktioniert

    – jalf

    4. Mai 2009 um 23:12 Uhr

  • Gibt es keine Optionen, wenn der MinGw-Compiler verwendet wird?

    – Tebe

    5. Januar 2013 um 1:08 Uhr

1646640615 390 Wie offne ich einen stdfstream ofstream oder ifstream mit einem
Klammern

Verwenden std::wofstream, std::wifstream und std::wfstream. Sie akzeptieren Unicode-Dateinamen. Dateiname muss sein wstringAnordnung von wchar_ts, oder es muss haben _T() Makro oder Präfix Lvor dem Text.

Schau mal rein 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;
}

  • noside funktioniert sehr gut … schade, dass es nicht in der Standard-Boost-Distribution enthalten ist; aber es zum Laufen zu bringen ist ziemlich einfach … großartig, endlich ausweichen zu können 🙂

    Benutzer176145

    15. Dezember 2019 um 19:50 Uhr

1646640615 339 Wie offne ich einen stdfstream ofstream oder ifstream mit einem
Michael Häphrati

Verwenden

wfstream

anstatt

fstream

und

wofstream

anstatt

ofstream

und so weiter… Sie finden diese Informationen in der iosfwd Header-Datei.

  • noside funktioniert sehr gut … schade, dass es nicht in der Standard-Boost-Distribution enthalten ist; aber es zum Laufen zu bringen ist ziemlich einfach … großartig, endlich ausweichen zu können 🙂

    Benutzer176145

    15. Dezember 2019 um 19:50 Uhr

Wenn Sie Qt gemischt mit verwenden std::ifstream:

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

Notiere dass der std::basic_ifstream Der Konstruktor akzeptiert normalerweise kein a const w_char*aber auf in der MS-Implementierung von STL tut es. Bei anderen Implementierungen würden Sie wahrscheinlich anrufen qString.utf8()und verwenden Sie die const char* ctor.

  • Es gibt kein ofstream Konstrukteur das dauert ein std::wstring Streit. Dies scheint eine Antwort auf eine andere Frage zu sein.

    – Inspektionsfähig

    19. November 2020 um 21:08 Uhr

  • Das ist immer noch ungenau. Das zusätzliche basic_ifstream Konstruktoren sind eine Microsoft-spezifische Erweiterung ihrer C++-Bibliotheksimplementierung. Andere Compiler für Windows können diese bereitstellen oder auch nicht. Unabhängig davon, wie diese Antwort erklärt, müssen Sie sich keine Gedanken über Zeichencodierungen oder den überhaupt zu verwendenden Konstruktor machen. Übergeben Sie einfach a filesystem::path und es funktioniert auf jedem Betriebssystem.

    – Inspektionsfähig

    24. November 2020 um 15:45 Uhr

  • @IInspectable Erneut aktualisiert. Nicht jeder kann C++17 verwenden. Meine Antwort sollte Leuten helfen, die Qt verwenden.

    – Andreas Häferburg

    27. November 2020 um 10:54 Uhr

  • Wenn Sie C++17 oder die Implementierung der C++-Standardbibliothek von Microsoft nicht verwenden können, gibt es keine sicheren Alternativen. Das Übergeben einer UTF-8-codierten Zeichenfolge für eine bestimmte Plattform ist entweder nicht sicher oder als nicht sicher dokumentiert oder als sicher dokumentiert. Schätzen Sie sich glücklich, wenn Sie zu den letzten beiden Kategorien gehören, obwohl Sie sich realistischerweise in der ersten wiederfinden werden. In diesem Fall die Empfehlung zu verwenden utf8() ist fast böswillig, da es häufig nicht fehlschlägt.

    – Inspektionsfähig

    27. November 2020 um 12:27 Uhr

  • @IInspectable Ich weiß nicht, was du von mir willst. Gibt es Ihrer Meinung nach etwas, das getan werden muss? Warum benutzt du ein Wort wie “bösartig”? Das ist keine konstruktive Art, auf ein gemeinsames Ziel hinzuarbeiten.

    – Andreas Häferburg

    28. November 2020 um 9:49 Uhr

964260cookie-checkWie öffne ich einen std::fstream (ofstream oder ifstream) mit einem Unicode-Dateinamen?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy