2009-04-06 19 views
12

Tengo un problema con el código siguiente:NSLog codificación incorrecta

NSString *[email protected]"你好"; 
char temp[200]; 
strcpy(temp, [strValue UTF8String]); 
printf("%s", temp); 
NSLog(@"%s", temp); 

en la primera línea de los códigos, dos caracteres chinos están entre comillas dobles. El problema es que la función printf puede mostrar los caracteres chinos correctamente, pero NSLog no puede.


Gracias a todos. Descubrí una solución para este problema. Foundation usa UTF-16 por defecto, así que para usar NSLog para generar la cadena c en el ejemplo, tengo que usar cStringUsingEncoding para obtener UTF-16 c string y usar% S para reemplazar% s.

NSString *[email protected]"你好"; 
char temp[200]; 
strcpy(temp, [strValue UTF8String]); 
printf("%s", temp); 
strcpy(temp, [strValue cStringUsingEncoding:NSUTF16LittleEndianStringEncoding]); 
NSLog(@"%S", temp); 

Respuesta

2

Sé que probablemente esté buscando una respuesta que lo ayude a comprender lo que está sucediendo.

Pero esto es lo que podría hacer para resolver su problema en este momento:

NSLog(@"%@", strValue); 
4

Mi conjetura es que NSLog asume una codificación diferente para los 8 bits C-secuencias que UTF-8, y puede ser uno que no admite caracteres chinos. Incómoda, ya que es, puede probar esto:

NSLog(@"%@", [NSString stringWithCString: temp encoding: NSUTF8StringEncoding]); 
10

de NSLog% s especificador de formato es en la codificación del sistema, que parece estar siempre MacRoman y no Unicode, por lo que sólo puede mostrar caracteres de codificación MacRoman. La mejor opción con NSLog es utilizar el especificador de formato de objeto nativo% @ y pasar el NSString directamente en lugar de convertirlo en una cadena C. Si solo tiene una cadena C y desea usar NSLog para mostrar un mensaje en lugar de printf o asl, deberá hacer algo como Don sugiere para convertir primero la cadena a un objeto NSString.

Así que, en parte, debe mostrar la cadena esperada:

NSString *str = @"你好"; 
const char *cstr = [str UTF8String]; 
NSLog(@"%@", str); 
printf("%s\n", cstr); 
NSLog(@"%@", [NSString stringWithUTF8String:cstr]); 

Si decide utilizar el nivel del mar, tenga en cuenta que si bien acepta cadenas en formato UTF8 y pasa a la codificación correcta para el demonio syslog (por lo se mostrará correctamente en la consola), codifica la cadena de codificación visual cuando se muestra en el terminal o se registra en un identificador de archivo, por lo que los valores no ASCII se mostrarán como secuencias de caracteres escapadas.

-1
# define NSLogUTF8(a,b) NSLog(a,[NSString stringWithCString:[[NSString stringWithFormat:@"%@",b] cStringUsingEncoding:NSUTF8StringEncoding] encoding:NSNonLossyASCIIStringEncoding]) 

#define NSLogUTF8Ex(a,b) NSLog(a,[MLTool utf8toNString:[NSString stringWithFormat:@"%@",b]]) 

+(NSString*)utf8toNString:(NSString*)str{ 
    NSString* strT= [str stringByReplacingOccurrencesOfString:@"\\U" withString:@"\\u"]; 
    //NSString *strT = [strTemp mutableCopy]; 
    CFStringRef transform = CFSTR("Any-Hex/Java"); 
    CFStringTransform((__bridge CFMutableStringRef)strT, NULL, transform, YES); 

    return strT; 
} 
+0

Buen enfoque :-) ¿Funcionará con los espacios en blanco entre '#' y 'define'? Además, tal vez una línea de explicación puede ser útil, ya que la línea de código es muy larga y, por lo tanto, no es fácil de leer. –

+0

@peter_the_oak Trabajo perfecto para mí – Gank

Cuestiones relacionadas