No imaginaría algo tan básico como abrir un archivo usando la biblioteca estándar de C++ para una aplicación de Windows era complicado ... pero parece ser así. Por Unicode aquí me refiero a UTF-8, pero puedo convertir a UTF-16 o lo que sea, el punto es obtener una instancia ofstream a partir de un nombre de archivo Unicode. Antes de hackear mi propia solución, ¿hay una ruta preferida aquí? Especialmente uno multiplataforma?¿Cómo abrir un std :: fstream (ofstream o ifstream) con un nombre de archivo unicode?
Respuesta
La biblioteca estándar de C++ no es compatible con Unicode. char
y wchar_t
no son necesarios para ser codificaciones Unicode.
En Windows, wchar_t
es UTF-16, pero no hay soporte directo para UTF-8 nombres de archivo en la biblioteca estándar (el char
tipo de datos no es Unicode en Windows)
Con MSVC (y por lo tanto el TEL Microsoft) , se proporciona un constructor para FileStreams que tiene un nombre de archivo const wchar_t*
, lo que permite crear la corriente como:
wchar_t const name[] = L"filename.txt";
std::fstream file(name);
sin embargo, esta sobrecarga no es especificado por el estándar de C++ 11 (lo único que garantiza la presencia de la char
versión basada). 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 OS'es wchar_t
puede no ser UTF16. Entonces, en general, esto no es portátil. La apertura de una secuencia con un nombre de archivo wchar_t
no está definida de acuerdo con la norma, y la especificación del nombre de archivo en char
s puede ser difícil porque la codificación utilizada por char varía entre OS 's.
¿Qué quiere decir con "fstream está garantizado para aceptar ambos wchar_t ..."? No tengo acceso al estándar 98 oficial, pero no puedo encontrar la mención de un wchar_t * ctor para basic_fstream en n2857 (es decir, IIUC, el borrador actual de C++ 0x) –
Hmm, parece que tiene razón . Me corresponde corregir – jalf
@ Éric: de acuerdo, los constructores para basic_fstream se definen en 27.8.1.12 del estándar '03, y hay dos: no-args y char *.fstream es un basic_fstream
Las versiones actuales de Visual C++ std :: basic_fstream tienen un método open()
que toma un wchar_t * según http://msdn.microsoft.com/en-us/library/4dx08bh4.aspx.
¿Esto finalmente/teóricamente será portátil? –
No todos los SO y sistemas de archivos admiten nombres de archivos Unicode, por lo que no serían portátiles. De lo que puedo deducir, el wchar_t * open() y el constructor en fstream son extensiones de Microsoft porque NTFS admite nombres de archivo Unicode. –
o más bien, porque NTFS usa UTF16 para codificar nombres de archivo Unicode. Linux también admite nombres de archivo Unicode, pero usa UTF8, por lo que la versión normal de char * funciona allí – jalf
Utilice std::wofstream
, std::wifstream
y std::wfstream
. Aceptan un nombre de archivo Unicode. El nombre del archivo tiene que ser wstring
, una matriz de wchar_t
s, o tiene que tener _T()
macro, o el prefijo antes del texto.
¿Podría proporcionar pruebas de que 'std :: wfstream' es' Unicode'? Hasta mi modesto conocimiento, simplemente usan 'wchar_t', que es un caracter ancho, usualmente' 16-bits'. Pero el contenido podría o no ser 'Unicode'. –
Lo que quiero decir es que aceptan cadenas Unicode, lo que responde a la pregunta, ¿no? – Brackets
En realidad, responde la mitad de la pregunta: digamos que tienes tu ruta de archivo UTF16 en tu wfstream (o UTF8 en tu flujo de datos). Windows no acepta Unicode y devolverá la "URL incorrecta" si tiene algunos caracteres especiales (por ejemplo, chino). –
Tenga una mirada en 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;
}
- 1. Abrir fstream con archivo con nombre de archivo Unicode en Windows usando el compilador no MSVC
- 2. ¿Debo cerrar un std :: fstream?
- 3. abrir archivo con un nombre de archivo unicode?
- 4. ¿Cómo crear un std :: ofstream en un archivo temporal?
- 5. descriptor de archivo de un std :: fstream
- 6. ¿por qué las clases STL ifstream y ofstream no toman std :: string como nombres de archivo?
- 7. Obtener un std :: ostream ya sea desde std :: cout o std :: ofstream (archivo)
- 8. ¿Por qué debo incluir los encabezados iostream y fstream para abrir un archivo
- 9. Crear objeto fstream desde un archivo * puntero
- 10. Fstream no puede crear un nuevo archivo
- 11. ¿Qué permisos tiene un archivo escrito con fstream?
- 12. Cómo devolver un fstream (C++ 0x)
- 13. ¿Cómo puedo abrir un archivo Unicode con Perl?
- 14. ARCHIVO vs fstream
- 15. Java no puede abrir un archivo con valores Unicode subrogantes en el nombre de archivo?
- 16. std :: fstream no crea el archivo
- 17. C++ cómo escribir/leer ofstream en Unicode/UTF8
- 18. C++ ¿Puedo reutilizar fstream para abrir y escribir varios archivos?
- 19. ¿Cómo puedo usar delimitadores no predeterminados cuando leo un archivo de texto con std :: fstream?
- 20. C++ fstream - Creando banderas de formato propias
- 21. Diseño de clase std :: ifstream
- 22. ¿cómo puedo leer exactamente 128 bytes de un fstream en un objeto de cadena?
- 23. Anónimo std :: ofstream maneja matriz de caracteres erróneamente
- 24. ¿Cuándo fallará ofstream :: open?
- 25. Comprobando si un archivo se abrió correctamente con ifstream
- 26. Abrir un archivo pdf programáticamente en un destino con nombre
- 27. ¿Cuál es la diferencia entre abrir un archivo con ios :: binary o ios :: out o ambos?
- 28. ¿Cómo abrir un archivo en PHP que tenga caracteres Unicode en su nombre?
- 29. Convierte ifstream en istream
- 30. ¿El std :: ofstream se puede mover?
que este es un [duplicado] (http://stackoverflow.com/questions/480849/windows-codepage-interactions-with-standard-cc-filenames) pregunta. Vea si alguna de las respuestas puede ayudar. –
¿Por qué no utiliza tipos de datos como 'std :: wofstream'? ¡Note el ** w **! – sergiol