¿Cómo abrir un std :: fstream (ofstream o ifstream) con un nombre de archivo unicode?

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

  •  03-07-2019
  •  | 
  •  

Pregunta

No imaginaría que algo tan básico como abrir un archivo usando la biblioteca estándar de C ++ para una aplicación de Windows fuera complicado ... pero parece serlo. Por Unicode aquí me refiero a UTF-8, pero puedo convertir a UTF-16 o lo que sea, el punto es obtener una instancia corriente de un nombre de archivo Unicode. Antes de hackear mi propia solución, ¿hay una ruta preferida aquí? ¿Especialmente uno multiplataforma?

¿Fue útil?

Solución

La biblioteca estándar de C ++ no es compatible con Unicode. No se requiere que char y wchar_t sean codificaciones Unicode.

En Windows, wchar_t es UTF-16, pero no hay soporte directo para los nombres de archivo UTF-8 en la biblioteca estándar (el tipo de datos char no es Unicode en Windows)

Con MSVC (y, por lo tanto, el STL de Microsoft), se proporciona un constructor para filestreams que toma un nombre de archivo const wchar_t * , lo que le permite crear la secuencia como:

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

Sin embargo, esta sobrecarga no está especificada por el estándar C ++ 11 (solo garantiza la presencia de la versión basada en char ). Tampoco está presente en implementaciones alternativas de STL como libstdc ++ de GCC para MinGW (-w64), a partir de la versión g ++ 4.8.x.

Tenga en cuenta que al igual que char en Windows no es UTF8, en otros sistemas operativos wchar_t puede no ser UTF16. Entonces, en general, es probable que esto no sea portátil. Abrir una secuencia con un nombre de archivo wchar_t no está definido de acuerdo con el estándar, y especificar el nombre de archivo en char s puede ser difícil porque la codificación utilizada por char varía entre los sistemas operativos ' es.

Otros consejos

Las versiones actuales de Visual C ++ the std :: basic_fstream tienen un método open () que toma un wchar_t * de acuerdo con http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx .

Desde C ++ 17, hay una forma multiplataforma para abrir un std :: fstream con un nombre de archivo Unicode usando std :: filesystem :: path sobrecarga. Hasta C ++ 20, puede crear una ruta desde una cadena UTF-8 con std :: sistema de archivos :: u8path . Ejemplo:

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

Después de C ++ 20, puede crear una ruta pasando UTF-8 al constructor: std :: filesystem :: path (u8 " ? ? ? ? ? ") (u8path quedará en desuso) .

Utilice std :: wofstream , std :: wifstream y std :: wfstream . Aceptan nombres de archivo unicode. El nombre del archivo debe ser wstring , una matriz de wchar_t s, o debe tener una macro _T () o el prefijo L antes del texto.

Eche un vistazo 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;
}

Si está usando Qt mezclado con std :: ifstream :

return std::wstring(reinterpret_cast<const wchar_t*>(qString.utf16()));
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top