Comment ouvrir un std :: fstream (ofstream ou ifstream) avec un nom de fichier unicode?

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

  •  03-07-2019
  •  | 
  •  

Question

Vous n’imagineriez pas que l’ouverture d’un fichier à l’aide de la bibliothèque standard C ++ pour une application Windows soit délicate ... mais cela semble être le cas. Par Unicode ici, je veux dire UTF-8, mais je peux convertir en UTF-16 ou peu importe, le point consiste à obtenir une instance ofstream à partir d'un nom de fichier Unicode. Avant de pirater ma propre solution, existe-t-il un itinéraire préféré ici? Surtout un multi-plateforme?

Était-ce utile?

La solution

La bibliothèque standard C ++ n'est pas compatible avec Unicode. char et wchar_t ne sont pas obligatoirement des codages Unicode.

Sous Windows, wchar_t correspond à UTF-16, mais les noms de fichiers UTF-8 ne sont pas directement pris en charge dans la bibliothèque standard (le type de données char n'est pas Unicode sous Windows).

Avec MSVC (et donc le STL Microsoft), un constructeur pour filestreams est fourni, qui prend un nom de fichier const wchar_t * , vous permettant de créer le flux en tant que:

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

Cependant, cette surcharge n'est pas spécifiée par la norme C ++ 11 (elle garantit uniquement la présence de la version basée sur char ). Il n’existe pas non plus dans d’autres implémentations STL telles que libstdc ++ de GCC pour MinGW (-w64), à partir de la version g ++ 4.8.x.

Notez que, tout comme char sur Windows n'est pas UTF8, sur d'autres systèmes d'exploitation, wchar_t ne peut pas être UTF16. Donc dans l'ensemble, ce n'est pas susceptible d'être portable. L’ouverture d’un flux sous un nom de fichier wchar_t n’est pas définie conformément à la norme et il peut être difficile de spécifier le nom de fichier dans char , car le codage utilisé par char varie es.

Autres conseils

Les versions actuelles de Visual C ++ std :: basic_fstream ont une méthode open () qui prend un wchar_t * selon http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx .

Depuis C ++ 17, il existe un moyen multi-plateforme pour ouvrir std :: fstream avec un nom de fichier Unicode à l'aide de std :: filesystem :: path surchargé. Jusqu'en C ++ 20, vous pouvez créer un chemin à partir d'une chaîne UTF-8 avec std :: système de fichiers :: u8path . Exemple:

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

Après C ++ 20, vous pouvez créer un chemin en transmettant UTF-8 au constructeur: std :: filesystem :: path (u8 " & # 12371; & # 12435; & # 12395; & # 12395; 12385; & # 12399; ") (u8path sera obsolète).

Utilisez std :: wofstream , std :: wifstream et std :: wfstream . Ils acceptent le nom de fichier unicode. Le nom de fichier doit être wstring , un tableau de wchar_t s ou une macro _T () , ou un préfixe L avant le texte.

Consultez 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;
}

Si vous utilisez Qt mélangé avec std :: ifstream :

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top