2013-12-12 2 views
5

Ho un NSString contenente un carattere Unicode più grande di U + FFFF, come il simbolo Simbolo musicale G CLEF ''. Posso creare NSString e visualizzarlo.Come gestire i caratteri Unicode a 32 bit in un NSString

NSString *s = @"A\U0001d11eB"; // "AB" 
NSLog(@"String = \"%@\"", s); 

Il registro è corretto e visualizza i 3 caratteri. Questo mi dice che l'NSString è ben fatto e non c'è alcun problema di codifica.

String = "AB" 

Ma quando provo a scorrere tutti i caratteri utilizzando il metodo

- (unichar)characterAtIndex:(NSUInteger)index 

tutto va male.

Il tipo unichar è di 16 bit, quindi mi aspetto di ottenere il carattere errato per il simbolo musicale. Ma anche la lunghezza della stringa è errata!

NSLog(@"Length = %d", [s length]); 
for (int i=0; i<[s length]; i++) 
{ 
    NSLog(@" Character %d = %c", i, [s characterAtIndex:i]); 
} 

display

Length = 4 
     Character 0 = A 
     Character 1 = 4 
     Character 2 = . 
     Character 3 = B 

Quali metodi devo usare per analizzare correttamente il mio NSString e ottenere i miei 3 caratteri unicode? Idealmente il metodo giusto dovrebbe restituire un tipo come wchar_t al posto di UNICHAR.

Grazie

risposta

5
NSString *s = @"A\U0001d11eB"; 
NSData *data = [s dataUsingEncoding:NSUTF32LittleEndianStringEncoding]; 
const wchar_t *wcs = [data bytes]; 
for (int i = 0; i < [data length]/4; i++) { 
    NSLog(@"%#010x", wcs[i]); 
} 

uscita:

 
0x00000041 
0x0001d11e 
0x00000042 

(. Il codice presuppone che wchar_t ha una dimensione di 4 byte e la codifica little-endian)

length e charAtIndex: no dà il risultato previsto perché \U0001d11e è memorizzato internamente come UTF-16 "surrogata paio".

Un altro metodo utile per le stringhe Unicode generali è

[s enumerateSubstringsInRange:NSMakeRange(0, [s length]) 
       options:NSStringEnumerationByComposedCharacterSequences 
      usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) { 
    NSLog(@"%@", substring); 
}]; 

uscita:

 
A 

B 
+0

Questo risponde perfettamente alla mia domanda. Grazie mille Martin! – PatrickV