Richard Garfield Richard Garfield - 1 month ago 8
Objective-C Question

NSString stringWithCString not showing special characters?

I'm using

[NSString stringWithFormat:@"%C",(unichar)decimalValueX];


but I have to call it thousands of times and its simply too slow.

As an alternative I tried this:

sprintf (cString, "%C", (unichar)decimalValueX);
[NSString stringWithCString:cString encoding:NSUTF16StringEncoding];


but no characters are correctly transalted.

If I try UTF8 instead of 16:

sprintf (cString, "%C", (unichar)decimalValueX);
[NSString stringWithCString:cString encoding:NSUTF8StringEncoding];


I get alphanumeric, but I don't get foreign characters or other special characters.

Can anyone explain whats going on? Or how to make stringWithFormat faster?

Thanks!

Answer

It seems that the %C format does not work with sprintf and related functions and non-ASCII characters. But there is a simpler method: stringWithCharacters:length: creates an NSString directly from a unichar array (UTF-16 code points). For a single unichar this would be just

NSString *string = [NSString stringWithCharacters:&decimalValueX length:1];

Example:

unichar decimalValueX = 8364; // The Euro character
NSString *string = [NSString stringWithCharacters:&decimalValueX length:1];
NSLog(@"%@", string); // €

Example for multiple UTF-16 code points:

unichar utf16[] = { 945, 946, 947 };
NSString *string3 = [NSString stringWithCharacters:utf16 length:3];
NSLog(@"%@", string3); // αβγ

For characters outside of the "basic multilingual plane" (i.e. characters > U+FFFF) you would have to use 2 UTF-16 code points per character (surrogate pair). Or use a different API like

uint32_t utf32[] = { 128123, 128121 };
NSString *string4 = [[NSString alloc] initWithBytes:utf32 length:2*4 encoding:NSUTF32LittleEndianStringEncoding];
NSLog(@"%@", string4); //