2011-09-21 33 views
7

Estoy tratando de imprimir una cadena wchar_t *. código va a continuación:char vs wchar_t

#include <stdio.h> 
#include <string.h> 
#include <wchar.h> 

char *ascii_ = "中日友好"; //line-1 
wchar_t *wchar_ = L"中日友好"; //line-2 

int main() 
{ 
    printf("ascii_: %s\n", ascii_); //line-3 
    wprintf(L"wchar_: %s\n", wchar_); //line-4 
    return 0; 
} 

//Output 
ascii_: 中日友好 

Pregunta:

  1. Aparentemente no debería asignar caracteres CJK a char * puntero en la línea-1, pero sólo lo hice, y la salida de la línea -3 es correcto, ¿por qué? ¿Cómo podría printf() en la línea 3 darme los caracteres no ascii? ¿Conoce la codificación de alguna manera?

  2. Supongo que el código en la línea-2 y la línea-4 es correcto, pero ¿por qué no obtuve ningún resultado de la línea 4?

+0

¿Qué compilador estás usando? GCC se predetermina a Utf-8 en la mayoría de las plataformas. Parece un problema de codificación para mí. – cyco130

+0

@ cyco130, sí, gcc – Alcott

Respuesta

8

En primer lugar, generalmente no es una buena idea usar caracteres que no sean ASCII en el código fuente. Lo que probablemente está sucediendo es que los caracteres chinos están siendo codificados como UTF-8, que funciona con ascii.

Ahora, en cuanto a por qué el wprintf() no está funcionando. Esto tiene que ver con la orientación del flujo. Cada flujo solo se puede establecer en normal o ancho. Una vez configurado, no se puede cambiar. Se establece la primera vez que se usa. (que es ascii debido al printf). Después de eso, el wprintf no funcionará debido a una orientación incorrecta.

En otras palabras, una vez que usa printf() debe seguir usando printf(). Del mismo modo, si comienza con wprintf(), debe seguir usando wprintf().

No puede entremezclar printf() y wprintf(). (Excepto en Windows)

EDIT:

Para responder a la pregunta de por qué la línea wprintf no funciona incluso por sí mismo. Probablemente sea porque el código se está compilando para que el formato UTF-8 de 中日友好 se almacene en wchar_. Sin embargo, wchar_t necesita una codificación Unicode de 4 bytes. (2 bytes) de Windows

Así que hay dos opciones que se me ocurren:

  1. no se moleste con wchar_t, y sólo se adhieren con múltiples bytes char s. Esta es la manera fácil, pero puede romperse si el sistema del usuario no está configurado en la configuración regional china.
  2. Utilice wchar_t, pero deberá codificar los caracteres chinos mediante secuencias de escape Unicode. Obviamente, esto hará que no se pueda leer en el código fuente, pero funcionará en cualquier máquina que pueda imprimir fuentes de caracteres chinos, independientemente de la configuración regional.
+0

si uso unicode escape seq, tengo que averiguar cada palabra china, ¿verdad? Eso será mucho trabajo por hacer: P – Alcott

+1

Correcto. Sin embargo, estoy seguro de que esto es lo suficientemente común como para encontrar una herramienta en línea que puede simplemente copiar y pegar el texto en chino y le dará la secuencia de escape de Unicode. Y para mantener el código legible, puede mantener el texto chino real junto a la secuencia de escape como un comentario. – Mysticial

+0

gracias Mysticial – Alcott

6

La línea 1 no es ascii, es la codificación multibyte utilizada por el compilador en tiempo de compilación. En sistemas modernos, probablemente sea UTF-8. printf no conoce la codificación. Simplemente está enviando bytes a stdout, y siempre que las codificaciones coincidan, todo está bien.

Un problema que debe tener en cuenta es que las líneas 3 y 4 invocan conjuntamente un comportamiento no definido. No puede mezclar carácter basado en caracteres y caracteres anchos en el mismo FILE (stdout).Después de la primera operación, el FILE tiene una "orientación" (ya sea de byte o de ancho), y después de eso cualquier intento de realizar operaciones de orientación opuesta da como resultado UB.

+0

Comentando el La línea printf(), obtuve algunos resultados pero no los caracteres chinos. ¿Por qué? – Alcott

+0

Probablemente la codificación de la configuración regional sea incorrecta. –

+0

codificación del entorno local? ¿Como arreglarlo? – Alcott

1

Está omitiendo un paso y, por lo tanto, piensa de la manera incorrecta.

Tiene un archivo C en el disco, que contiene bytes. Tienes una cuerda "ASCII" y una cuerda ancha.

La cadena ASCII toma los bytes exactamente como están en la línea 1 y los emite. Esto funciona siempre que la codificación del lado del usuario sea la misma que la del lado del programador.

La cadena ancha primero decodifica los bytes dados en puntos de código Unicode y se almacena en el programa, tal vez esto vaya mal de su lado. En la salida, se codifican de nuevo de acuerdo con la codificación del lado del usuario. Esto garantiza que estos caracteres se emitan como están destinados, no como se ingresan.

O bien su compilador asume la codificación incorrecta, o su terminal de salida está configurado de la manera incorrecta.