Domanda

Non immagineresti qualcosa di semplice come aprire un file usando la libreria standard C ++ per un'applicazione Windows era complicato ... ma sembra che lo sia. Con Unicode qui intendo UTF-8, ma posso convertirlo in UTF-16 o qualsiasi altra cosa, il punto è ottenere un'istanza ofstream da un nome file Unicode. Prima di hackerare la mia soluzione, c'è un percorso preferito qui? Soprattutto multipiattaforma?

È stato utile?

Soluzione

La libreria standard C ++ non è compatibile con Unicode. char e wchar_t non devono essere codifiche Unicode.

Su Windows, wchar_t è UTF-16, ma non esiste un supporto diretto per i nomi di file UTF-8 nella libreria standard (il tipo di dati char non è Unicode su Windows)

Con MSVC (e quindi Microsoft STL), viene fornito un costruttore per filestreams che prende un const wchar_t * , permettendoti di creare lo stream come:

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

Tuttavia, questo sovraccarico non è specificato dallo standard C ++ 11 (garantisce solo la presenza della versione basata su char ). Inoltre non è presente su implementazioni STL alternative come libstdc ++ di GCC per MinGW (-w64), a partire dalla versione g ++ 4.8.x.

Nota che, proprio come char su Windows non è UTF8, su wchar_t di altri sistemi operativi potrebbe non essere UTF16. Quindi, nel complesso, non è probabile che questo sia portatile. Aprire uno stream con un wchar_t non è definito secondo lo standard e specificare il nome del file in char può essere difficile perché la codifica utilizzata da char varia tra SO ' es.

Altri suggerimenti

Le versioni correnti di Visual C ++ the std :: basic_fstream hanno un metodo open () che accetta un wchar_t * secondo http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx .

A partire da C ++ 17, esiste un modo multipiattaforma per aprire uno std :: fstream con un nome file Unicode usando std :: filesystem :: path sovraccarico. Fino a C ++ 20, è possibile creare un percorso da una stringa UTF-8 con std :: filesystem :: u8path . Esempio:

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

Dopo C ++ 20, puoi creare un percorso passando UTF-8 al costruttore: std :: filesystem :: path (u8 " ? ? ? ? ? ") (u8path sarà deprecato) .

Usa std :: wofstream , std :: wifstream e std :: wfstream . Accettano il nome file unicode. Il nome del file deve essere wstring , array di wchar_t , oppure deve avere la macro _T () o il prefisso L prima del testo.

Dai un'occhiata a 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;
}

Se stai usando Qt mescolato con std :: ifstream :

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top