将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 }