将NSString转换为UTF32和从UTF32转换

我正在使用包含UTF32字符的hex代码的数据库。 我想把这些字符存储在一个NSString中。 我需要有两个例程转换例程。

要将NSString的第一个字符转换为unicode值,这个例程似乎工作:

const unsigned char *cs = (const unsigned char *) [s cStringUsingEncoding:NSUTF32StringEncoding]; uint32_t code = 0; for ( int i = 3 ; i >= 0 ; i-- ) { code <<= 8; code += cs[i]; } return code; 

但是,我无法做到相反(即采取一个单一的代码,并将其转换成NSString)。 我以为只要按照正确的顺序创build一个UTF32字符的cstring,然后用正确的顺序创build一个NSStringstring,就可以完成与上述相反的操作。

但是,转换到/从cstrings似乎是不可逆转的。

例如,我试过这段代码,“tmp”string不等于原始string“s”。

 char *cs = [s cStringUsingEncoding:NSUTF32StringEncoding]; NSString *tmp = [NSString stringWithCString:cs encoding:NSUTF32StringEncoding]; 

有谁知道我在做什么错? 我应该使用“wchar_t”的cstring而不是char *?

任何帮助是极大的赞赏!

谢谢,罗恩

你有几个合理的select。

1.转换

首先是将您的UTF32转换为UTF16并将其与NSString一起使用,因为UTF16是NSString的“本地”编码。 事实上并非如此。 如果UTF32字符在BMP中(例如,高两个字节是0),则可以直接将其转换为unichar 。 如果在任何其他平面上,则可以将其转换为UTF16字符的代理对。 您可以在维基百科页面上find规则。 但是,一个快速(未经testing)的转换看起来像

 UTF32Char inputChar = // my UTF-32 character inputChar -= 0x10000; unichar highSurrogate = inputChar >> 10; // leave the top 10 bits highSurrogate += 0xD800; unichar lowSurrogate = inputChar & 0x3FF; // leave the low 10 bits lowSurrogate += 0xDC00; 

现在您可以同时使用两个字符创build一个NSString:

 NSString *str = [NSString stringWithCharacters:(unichar[]){highSurrogate, lowSurrogate} length:2]; 

要倒退,可以使用[NSString getCharacters:range:]来获取unichar,然后使用代理对algorithm来取回UTF32字符(任何不在0xD800-0xDFFF范围内的0xD800-0xDFFF都应该转换为UTF32直接)。

2.字节缓冲区

您的另一个select是让NSString直接执行转换,而不使用cStrings。 要将UTF32值转换为NSString,可以使用如下所示的内容:

 UTF32Char inputChar = // input UTF32 value inputChar = NSSwapHostIntToLittle(inputChar); // swap to little-endian if necessary NSString *str = [[[NSString alloc] initWithBytes:&inputChar length:4 encoding:NSUTF32LittleEndianStringEncoding] autorelease]; 

为了让它恢复,可以使用

 UTF32Char outputChar; if ([str getBytes:&outputChar maxLength:4 usedLength:NULL encoding:NSUTF32LittleEndianStringEncoding options:0 range:NSMakeRange(0, 1) remainingRange:NULL]) { outputChar = NSSwapLittleIntToHost(outputChar); // swap back to host endian // outputChar now has the first UTF32 character }