2012-03-08 11 views
9

La API de Windows parece grande en UNICODE, crea un nuevo proyecto en Visual C++ y lo establece en UNICODE de forma predeterminada.
Y yo tratando de ser un buen programador de Windows, quiero usar UNICODE.C++ UNICODE y STL

El problema es la biblioteca de C++ estándar y STL (como std :: string o std :: runtime_error) no funcionan bien con UNICODE cuerdas. que sólo puede pasar un std :: string , o una runtime_error char* a std ::, y estoy bastante seguro de std :: string no soporta UNICODE.

Entonces mi pregunta es, ¿cómo debo usar cosas como std :: runtime_error? ¿Debo mezclar UNICODE y regular ANSI? (Creo que esta es una mala idea ...)
¿Solo uso ANSI en todo mi proyecto? (Prefiero no ...) ¿O qué?

+2

Son excepciones, ¿cree que necesita internacionalizarlas y realmente necesita soporte unicode para ellas? – PlasmaHH

+0

Puedes usar principalmente 'std :: wstring' en todas partes. 'std :: runtime_error' es una desafortunada excepción (¡sin juego de palabras!). – arx

+1

posible duplicado de [Excepciones con Unicode what()] (http: // stackoverflow.com/questions/3760731/exceptions-with-unicode-what) –

Respuesta

9

En general, no debe mezclar esas dos codificaciones. Sin embargo, los mensajes de excepción son solo de interés para el desarrollador (por ejemplo, en archivos de registro) y nunca se deben mostrar al usuario (pero consulte el comentario de Jim para una advertencia importante).

Por lo tanto, usted está en el lado seguro si usa UNICODE para toda su interfaz con la cara del usuario y aún utiliza std::exception etc. detrás de las escenas para los mensajes del desarrollador. No debería haber necesidad alguna vez de convertir entre los dos.

Además, es un buen truco para definir un typedef para UNICODE cadenas -independiente en C++:

typedef std::basic_string<TCHAR> tstring; 

... y de manera análoga a definir tcout, tcin etc. condicionalmente:

#ifdef UNICODE 
    std::wostream& tcout = std::wcout; 
    std::wostream& tcerr = std::wcerr; 
    std::wostream& tclog = std::wclog; 
    std::wistream& tcin = std::wcin; 
#else 
    std::ostream& tcout = std::cout; 
    std::ostream& tcerr = std::cerr; 
    std::ostream& tclog = std::clog; 
    std::istream& tcin = std::cin; 
#endif 
+3

Creo que hay un argumento para hacer que para casos como archivos de registro, usted debería usar cadenas Unicode. Los archivos de registro a menudo mezclan los datos del usuario con los datos del sistema y los datos del usuario muy probablemente incluyan contenido Unicode. Siempre podría suponer excepciones ANSI, pero una buena excepción podría incluir una ruta de archivo (para una excepción de archivo no encontrado, por ejemplo) y esa ruta podría incluir caracteres Unicode). –

+0

Pulgar hacia arriba para el truco typedef. Pero, ¿qué ocurre si quiero que los mensajes de error se muestren al usuario para que informe/identifique problemas? EDIT: casi todo lo que Jim Lamb dijo. – Josh

+0

@Jim Punto verdadero. Honestamente, no había considerado eso. –

0

Para trabajar con la API Unicode de Windows, simplemente use las versiones de cadenas anchas - wstring, etc. No ayudará con exception::what(), pero para eso puede usar la codificación UTF-8 si realmente necesita Unicode.

1

Tome una mirada en este artículo (bastante antiguo ahora) en CodeProject: Upgrading an STL-based application to use Unicode. Cubre los problemas que es probable que golpees si estás usando el STL extensivamente. No debería ser tan malo y, en términos generales, vale la pena usar cuerdas anchas.

+1

Hmm, este artículo está muy desactualizado. Por ejemplo, dice que 'wchar_t' es un typedef de' unsigned short' que causa problemas de sobrecarga. Esto no es cierto en los compiladores modernos. –