is it possible to convert NSString into unichar - objective-c

I have a NSString object and want to change it into unichar.
int decimal = [[temp substringFromIndex:2] intValue]; // decimal = 12298
NSString *hex = [NSString stringWithFormat:#"0x%x", decimal]; // hex = 0x300a
NSString *chineseChar = [NSString stringWithFormat:#"%C", hex];
// This statement log a different Chinese char every time I run this code
NSLog(#"%#",chineseChar);
When I see the log, It gives different character every time when I run my code.
m I missing something...?

The %C format specifier takes a 16-bit Unicode character (unichar) as input, not an NSString. You're passing in an NSString, which is getting reinterpreted as an integer character; since the string can be stored at a different address in memory each time you run, you get that address as an integer, which is why you get a different Chinese character every time you run your code.
Just pass in the character as an integer:
unichar decimal = 12298;
NSString *charStr = [NSString stringWithFormat:#"%C", decimal];
// charStr is now a string containing the single character U+300A,
// LEFT DOUBLE ANGLE BRACKET

How about -[NSString characterAtIndex:]? It wants a character index and returns a unichar.

Related

How to define a variable string format specifier

I have this line of code
// valueX is a long double (long double is a huge floating point)
NSString *value = [NSString stringWithFormat: #"%.10Lg", valueX];
This format specifier is specifying up to 10 decimal digits but I don't want to hard code this to 10.
I have this variable numberOfDigits that I want to be used to define the number of digits. For those itching to down vote this question, it is not so easy as it seems. I cannot substitute the 10 with %# because %.10Lg is a format specifier by itself.
OK, I can create a bunch of strings like #"%.5Lg", #"%.8Lg", #"%.9Lg"... and switch that, but I wonder if there is another way...
There is, if you read the manual pages for format specifiers. You can replace the precision with *, which means it will get taken from a parameter instead.
int numDigits = 10;
NSString *value = [NSString stringWithFormat:#"%.*Lg", numDigits, valueX];
I couldn't find this in the core foundation reference, but I know that this is written in the man 3 printf man page.
Dietrich's answer is the simplest and therefore best. Note that even if there wasn't a built-in way to specify the number of digits with a parameter you could still have done it by first building your format string and then using it:
- (NSString *) stringFromValue: (long double) value digits: (int) digits; {
//First create a format string. Use "%%" to escape the % escape char.
NSString *formatString =[NSString stringWithFormat: #"%%.%dLg", digits];
return [NSString stringWithFormat: formatString, value];
}

How to get an ascii value of a NSString*, pointing to a character?

When presented with an #"a", i'd like to be able to get it's ascii value of 97.
I thought this does it
NSString *c = [[NSString alloc] initWithString:#"a"];
NSLog(#"%d", [c intValue]); // Prints 0, expected 97
But ... you guessed it (or knew it :)) .. it does not.
How can i get an ascii value of a NSString*, pointing to a single character?
NSString *str = #"a";
unichar chr = [str characterAtIndex:0];
NSLog(#"ascii value %d", chr);
And why your method does not work is because you are operating on a STRING remember? Not a single character. Its still a NSString.
NSLog(#"%d",[c characterAtIndex:0]);
NSString class reference: The integer value of the receiver’s text, assuming a decimal representation and skipping whitespace at the beginning of the string. Returns INT_MAX or INT_MIN on overflow. Returns 0 if the receiver doesn’t begin with a valid decimal text representation of a number.
So it returned 0 because you called intValue on invalid decimal text representation of a number.

searching and replacing an extended ASCII in a string

a noob question here.
I am trying to make an automatic search and replace process for characters' ASCII values in a string.
so, I have a string constructed from a content of a UITextField
NSString *searchText;
searchText = (mmText.text);
then I do a little loop and check all entered characters for their ASCII values. if they're not in the allowed range I want to search and replace them with something else (? for now)
so let's say I am in the loop and I get to a ASCII 45 character (it's a minus sign):
int asciiCode = 45;
now I would like to find the ASCII 45 character in the string and replace it with a question mark
This is what I am doing at the moment:
NSString *ascStr = [NSString stringWithFormat:#"%c", asciiCode];
NSRange matchSpace;
matchSpace = [searchText rangeOfString: ascStr];
if (matchSpace.location == NSNotFound)
{}
else
NSMutableString *searchandReplace = [NSMutableString stringWithString: searchText];
[searchandReplace replaceCharactersInRange: [searchandReplace rangeOfString: ascStr] withString: #"?"];
mmText.text = searchandReplace;
}
This works fine for a regular ASCII value (0-255), but it doesn't seem to work for the extended ASCII values coming from foreign languages. For example when using the Korean language mode, one of the main character looks like a double crossed W, but when printed via NSLog it looks like a copyright sign. This is probably the reason the search and replace procedure doesn't work for it. It has an ASCII value of 8361.
any ideas ? thank you!
it turns out it was as simple as changing:
NSString *ascStr = [NSString stringWithFormat:#"%c", asciiCode];
to
NSString *ascStr = [NSString stringWithFormat:#"%C", asciiCode];
%c
8-bit unsigned character (unsigned char), printed by NSLog() as an ASCII character, or, if not an ASCII character, in the octal format \ddd or the Unicode hexadecimal format \udddd, where d is a digit
%C
16-bit Unicode character (unichar), printed by NSLog() as an ASCII character, or, if not an ASCII character, in the octal format \ddd or the Unicode hexadecimal format \udddd, where d is a digit

Casting or converting a char to an NSString in Objective-C

How do I convert a char to an NSString in Objective-C?
Not a null-terminated C string, just a simple char c = 'a'.
You can use stringWithFormat:, passing in a format of %c to represent a character, like this:
char c = 'a';
NSString *s = [NSString stringWithFormat:#"%c", c];
You can make a C-string out of one character like this:
char cs[2] = {c, 0}; //c is the character to convert
NSString *s = [[NSString alloc] initWithCString:cs encoding: SomeEncoding];
Alternatively, if the character is known to be an ASCII character (i. e. Latin letter, number, or a punctuation sign), here's another way:
unichar uc = (unichar)c; //Just extend to 16 bits
NSString *s = [NSString stringWithCharacters:&uc length:1];
The latter snippet with surely fail (not crash, but produce a wrong string) with national characters. For those, simple extension to 16 bits is not a correct conversion to Unicode. That's why the encoding parameter is needed.
Also note that the two snippets above produce a string with diferent deallocation requirements. The latter makes an autoreleased string, the former makes a string that needs a [release] call.

Converting long value to unichar* in objective-c

I'm storing large unicode characters (0x10000+) as long types which eventually need to be converted to NSStrings. Smaller unicode characters can be created as a unichar, and an NSString can be created using
[NSString stringWithCharacters:(const unichar *)characters length:(NSUInteger)length]
So, I imagine the best way to get an NSString from the unicode long value would be to first get a unichar* from the long value. Any idea on how I might go about doing this?
Is there any reason you are storing the values as longs? For Unicode storage you only need to store the values as UInt32, which would then make it easy to interpret the data as UTF-32 by doing something like this:
int numberOfChars = 3;
UInt32* yourStringBuffer = malloc(sizeof(UInt32) * numberOfChars);
yourStringBuffer[0] = 0x2F8DB; //杞
yourStringBuffer[1] = 0x2318; //⌘
yourStringBuffer[2] = 0x263A; //☺
NSData* stringData = [NSData dataWithBytes:yourStringBuffer length:sizeof(UInt32) * numberOfChars];
//set the encoding according to the current byte order
NSStringEncoding encoding;
if(CFByteOrderGetCurrent() == CFByteOrderBigEndian)
encoding = NSUTF32BigEndianStringEncoding;
else
encoding = NSUTF32LittleEndianStringEncoding;
NSString* string = [[NSString alloc] initWithData:stringData encoding:encoding];
free(yourStringBuffer);
NSLog(#"%#",string);
//output: 杞⌘☺