Pregunta sobre unicode, windows, fstream, c++, utf-8 – Los caracteres fstream :: open () Unicode o no Ascii no funcionan (con std :: ios :: out) en Windows

3

En un proyecto de C ++, quiero abrir un archivo (fstream::open()) (lo que parece ser un problema importante). La compilación de Windows de mi programa falla miserablemente.

Archivo "ä" (UTF-8 0xC3 0xA4)

<code>std::string s = ...;
//Convert s
std::fstream f;
f.open(s.c_str(), std::ios::binary | std::ios::in); //Works (f.is_open() == true)
f.close();
f.open(s.c_str(), std::ios::binary | std::ios::in | std::ios::out); //Doesn't work
</code>

La cuerdas está codificado en UTF-8, pero luego se convierte de UTF-8 a Latin1 (0xE4). Estoy usando Qt, entoncesQString::fromUtf8(s.c_str()).toLocal8Bit().constData().

¿Por qué puedo abrir el archivo para leer, pero no para escribir?

Archivo "и" (UTF-8 0xD0 0xB8)

Mismo código, no funciona en absoluto.

Parece que este personaje no cabe en el conjunto de caracteres Windows-1252. ¿Cómo puedo abrir una fuente de este tipo (no estoy usando MSVC, por lo quenofstream::open(const wchar_t*, ios_base::openmode))?

¿Qué compilador y biblioteca C estás usando? Si está utilizando, por ejemplo, MinGW, aún puede usar funciones de MS CRT, como_wfopen. Si está utilizando un tiempo de ejecución de C diferente (como el libc de Cygwin GCC), entonces está a merced del soporte de Unicode de la biblioteca de tiempo de ejecución. Adam Rosenfield
Respuesta larga al comentario corto: verutf8everywhere.org acerca de cómo hacerlo bien. Pavel Radzivilovsky
Su biblioteca estándar de C y C ++ necesita ser compatible con Unicode (es decir, tienen que convertir sus cadenas de entrada UTF-8 a UTF-16 y luego llamarCreateFileW). Si no lo hacen, no tienes suerte, entonces probablemente debas llamarCreateFileW directamente. Philipp
@Adam Rosenfield Estoy usando mingw32-g ++ - 4.6.2. _wfopen () devuelve un puntero de ARCHIVO *, ¿cómo abro un objeto fstream de esa manera? basic6

Tu respuesta

2   la respuesta
3

hay una extensión no estándar (sobrecarga) para permitir el soporte de Unicode para cadenas codificadas en UTF-16.

Simplemente pase UTF-16 codificado std :: wstring a fstream :: open (). Esta es la única manera de hacer que funcione con fstream.

Puede leer más sobre lo que considero que es la forma más fácil de admitir Unicode en Windows aquí:http://utf8everywhere.org/

@ basic6: por favor lee elfunciones de conversión sección. AFAIK la biblioteca de ahora también debería funcionar en MinGW. ybungalobill
Probablemente esa sea la solución adecuada, pero AFAIK esta sobrecarga solo está disponible con MSVC, no con MinGW ("no hay una función coincidente para llamar a ..."). Y no uso el compilador de Microsoft, porque no he transferido el código en el que estoy trabajando actualmente a C ++ de Microsoft (en otras palabras, el código no se compilará y todavía no me he molestado en averiguar por qué). basic6
3

: fstream) en Windows, solo puede abrir un archivo si el nombre del archivo se puede codificar utilizando la página de códigos ANSI (CP_ACP) establecida actualmente.

Esto significa que puede haber archivos que simplemente no se pueden abrir utilizando estas API en Windows. A menos que Microsoft implemente soporte para establecer CP_ACP en CP_UTF8, entonces esto no puede ser el uso de la biblioteca estándar de Microsoft CRT o C ++.

(Windows ha tenido una característica llamada nombres de archivo "cortos" donde, cuando se habilita, cada archivo en la unidad tiene un nombre de archivo ASCII que se puede usar a través de API estándar. Sin embargo, esta característica desaparece, por lo que no representa una solución viable).

Preguntas relacionadas