2008-10-03 23 views
23

¿Cómo configuro la página de códigos para UTF-8 en un programa C de Windows?UTF-8 en Windows

Tengo una biblioteca de terceros que tiene fopen para abrir archivos. Puedo usar wcstombs para convertir mis nombres de archivo Unicode a la página de códigos actual, sin embargo, si el usuario tiene un nombre de archivo con un carácter fuera de la página de códigos, se rompe.

Lo ideal sería simplemente llamar a _setmbcp (65001) para configurar la página de códigos en UTF-8, sin embargo, la documentación de MSDN para _setmbcp indica que UTF-8 no es compatible.

¿Cómo puedo evitar esto?

Respuesta

25

Desafortunadamente, no hay forma de hacer que Unicode sea la página de códigos actual en Windows. Las constantes CP_UTF7 y CP_UTF8 son pseudocódigos, se usan solo en las funciones de conversión MultiByteToWideChar y WideCharToMultiByte, como mencionó Ben.

Tu problema es similar al de las clases de fstream C++. Los constructores de fstream aceptan solo los nombres char*, lo que hace imposible abrir un archivo con un verdadero nombre Unicode. La única solución ofrecida por VC era un hack: abra el archivo por separado y luego establezca el manejador en el objeto de transmisión. Me temo que esta no es una opción para usted, por supuesto, ya que la biblioteca de terceros probablemente no acepte identificadores.

La única solución que se me ocurre es crear un archivo temporal con un nombre que no sea Unicode, que esté vinculado al original y usarlo como parámetro.

10

Todas las API de Windows piensan en UTF-16, por lo que es mejor escribir un contenedor alrededor de su biblioteca que se convierta en los límites.

Curiosamente, Windows piensa UTF-8 es una página de códigos a los efectos de conversión, por lo que utilizar las mismas API como lo haría para convertir entre páginas de códigos:

std::wstring Utf8ToUtf16(const char* u8string) 
{ 
    int wcharcount = strlen(u8string); 
    wchar_t *tempWstr = new wchar_t[wcharcount]; 
    MultiByteToWideChar(CP_UTF8, 0, u8string, -1, tempWstr, wcharcount); 
    wstring w(tempWstr); 
    delete [] tempWstr; 
    return w; 
} 

Y algo de forma similar a convertir de nuevo .

-4

Utilice cygwin (que proporciona una configuración regional UTF-8 por defecto), o escriba su propio libc hack para Windows que realice las traducciones necesarias UTF-8 a UTF-16 y ajuste las funciones no estándar _wfopen etc.

+2

realmente? ¿Vas a sugerir eso? –