2009-04-06 12 views
12

Mam problem z następującym kodem:NSLog niepoprawne kodowanie

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

w pierwszej linii kodów, dwóch chińskich znaków są podwójnie cytowane. Problemem jest funkcja printf, która poprawnie wyświetla chińskie znaki, ale NSLog nie.


Dziękuję wszystkim. Wymyśliłem rozwiązanie tego problemu. Fundament używa domyślnie UTF-16, więc aby użyć NSLog do wyprowadzenia ciągu c w przykładzie, muszę użyć cStringUsingEncoding, aby pobrać ciąg znaków UTF-16 c i użyć% S, aby zastąpić% s.

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

Odpowiedz

2

Wiem, że prawdopodobnie szukasz odpowiedzi, która pomoże Ci zrozumieć, co się dzieje.

Ale to, co można zrobić, aby rozwiązać swój problem teraz:

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

Domyślam się, że NSLog zakłada inny kodowanie 8-bitowe C-ciągi niż UTF-8, a może to być taki, który nie obsługuje chińskich znaków. Niezgrabny jak to jest, można spróbować to:

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

NSLog za% s Format specifier jest w kodowaniu systemu, który wydaje się być zawsze MacRoman i nie Unicode, dzięki czemu można wyświetlać tylko znaki w kodowaniu MacRoman to. Najlepszym rozwiązaniem z NSLog jest użycie natywnego specyfikatora formatu obiektów% @ i bezpośrednie przekazanie NSString zamiast konwertowania go na ciąg C. Jeśli masz tylko ciąg C i chcesz użyć NSLog do wyświetlenia komunikatu zamiast printf lub asl, będziesz musiał zrobić coś takiego, jak Don sugeruje, aby najpierw przekonwertować ciąg na obiekt NSString.

Tak, wszystkie te powinny wykazywać oczekiwany ciąg:

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

Jeśli zdecydujesz się skorzystać npm, trzeba pamiętać, że chociaż akceptuje ciągi w formacie UTF-8 i przekazuje odpowiednie kodowanie do demona syslog (tak pojawi się poprawnie w konsoli), koduje kodowanie wizualne podczas wyświetlania na terminalu lub logowania do uchwytu pliku, więc wartości inne niż ASCII będą wyświetlane jako sekwencje znaków z sekwencjami specjalnymi.

-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

Dobre podejście :-) czy będzie działać z odstępami między '#' i 'define'? Być może pomocny może być również jeden wiersz objaśnień, ponieważ linia kodu jest bardzo długa i dlatego nie jest dobrze czytelna. –

+0

@peter_the_oak Praca idealna dla mnie – Gank