如何将unichar值转换为Objective-C中的NSString?

我有一个国际字符存储在unicharvariables。 这个字符不是来自文件或url。 variables本身只存储一个UTF-8格式的unsigned short(0xce91),并转换为希腊大写字母“A”。 我试图把这个字符放入一个NSStringvariables,但是我失败了。

我已经尝试了两种不同的方式,但都不成功:

unichar greekAlpha = 0xce91; //could have written greekAlpha = 'Α' instead. NSString *theString = [NSString stringWithFormat:@"Greek Alpha: %C", greekAlpha]; 

不好。 我有一些奇怪的汉字。 作为一个旁注,这与英文字符完美的作品。

然后我也试过这个:

 NSString *byteString = [[NSString alloc] initWithBytes:&greekAlpha length:sizeof(unichar) encoding:NSUTF8StringEncoding]; 

但是这也行不通。 我显然在做一些非常错误的事情,但我不知道是什么。 有人可以帮我吗? 谢谢!

由于0xce91采用UTF-8格式, %C预计采用UTF-16,所以上述简单的解决scheme将无法工作。 对于stringWithFormat:@"%C"的工作,你需要input0x391这是UTF-16的Unicode。

为了从UTF-8编码的unichar创build一个string,你需要首先将unicode分成它的八位字节,然后使用initWithBytes:length:encoding

 unichar utf8char = 0xce91; char chars[2]; int len = 1; if (utf8char > 127) { chars[0] = (utf8char >> 8) & (1 << 8) - 1; chars[1] = utf8char & (1 << 8) - 1; len = 2; } else { chars[0] = utf8char; } NSString *string = [[NSString alloc] initWithBytes:chars length:len encoding:NSUTF8StringEncoding]; 
 unichar greekAlpha = 0x0391; NSString* s = [NSString stringWithCharacters:&greekAlpha length:1]; 

现在你可以用任何你喜欢的方式把NSString合并到另一个。 但是,请注意,将希腊字母直接键入NSString文字现在是合法的。

上面的答案很好,但是没有考虑超过16位的UTF-8字符,例如省略符号 – 0xE2,0x80,0xA6。 这是对代码的调整:

 if (utf8char > 65535) { chars[0] = (utf8char >> 16) & 255; chars[1] = (utf8char >> 8) & 255; chars[2] = utf8char & 255; chars[3] = 0x00; } else if (utf8char > 127) { chars[0] = (utf8char >> 8) & 255; chars[1] = utf8char & 255; chars[2] = 0x00; } else { chars[0] = utf8char; chars[1] = 0x00; } NSString *string = [[[NSString alloc] initWithUTF8String:chars] autorelease]; 

注意不需要长度参数的string初始化方法。

这里是一个字符的UTF-8编码algorithm:

 if (utf8char<0x80){ chars[0] = (utf8char>>0) & (0x7F | 0x00); chars[1] = 0x00; chars[2] = 0x00; chars[3] = 0x00; } else if (utf8char<0x0800){ chars[0] = (utf8char>>6) & (0x1F | 0xC0); chars[1] = (utf8char>>0) & (0x3F | 0x80); chars[2] = 0x00; chars[3] = 0x00; } else if (utf8char<0x010000) { chars[0] = (utf8char>>12) & (0x0F | 0xE0); chars[1] = (utf8char>>6) & (0x3F | 0x80); chars[2] = (utf8char>>0) & (0x3F | 0x80); chars[3] = 0x00; } else if (utf8char<0x110000) { chars[0] = (utf8char>>18) & (0x07 | 0xF0); chars[1] = (utf8char>>12) & (0x3F | 0x80); chars[2] = (utf8char>>6) & (0x3F | 0x80); chars[3] = (utf8char>>0) & (0x3F | 0x80); } 

上面的代码是unichar foo = 'abc';的道德等价物unichar foo = 'abc';

问题是'Α'没有映射到C99第 6.4.4.4节“执行字符集”中的单个字节(我假定为UTF-8)10:

包含多个字符(例如'ab' )的整数字符常量的值,或包含不映射到单字节执行字符的字符或转义序列的值是实现定义的。

一种方法是使'ab'等于'a'<<8|b 。 一些Mac / iOS系统的头文件依赖于这样的东西,如OSType / FourCharCode / FourCC ; 在iOS中唯一想到的就是CoreVideo像素格式。 然而,这是不可移植的。

如果你真的想要一个unichar文字,你可以尝试L'A' (从技术上说,这是一个wchar_t文字,但在OS X和iOS上, wchar_t通常是UTF-16,所以它可以用于BMP内的东西)。 然而,只要使用@"Α" (只要你正确设置源字符编码就行)或@"\u0391" (至less从iOS 3 SDK开始工作)就简单多了。