Help with NSString of int's to NSString of ASCII characters? - iphone

I have implemented some code to convert a NSString of "text" to an NSString of (ASCII) ints, like so:
#"Hello" is converted to #"72 101 108 108 111"
However, I am having quite a bit of difficulty doing the opposite. Starting with a string of ints (with the spaces) and converting back to the plain string of text.
What I need: #"72 101 108 108 111" must be converted to #"Hello"
I have tried breaking up the input string into an int array, iterating through it, and using repeatedly the following:
[NSString stringWithFormat:#"%c", decCharArray[i]]
However, the problem with that is that it parses each particular digit into ASCII, converting the 7, the 2, the space, the 1, etc.
Thanks a ton in advance.

Sounds like you have the right approach. Try using [string componentsSeparatedByString:#" "] to split the string at the spaces. Then you can convert each of those to numbers, and back into strings.

There is no real magic on it. Since you'll be using ASCII, to convert an int
to a char all you have to do is an assignment, as you may already know:
char a = 65; /* a contains 'A' */
NSString has a very convenient method componentsSeparatedByString: that will
return an array of strings containing your numbers, and you can get an int
from a string with the intValue method. Thus, all you have to do is to split
the string and iterate through the components assigning their int value to a
char array. Here is an example function that does that:
NSString *
TextFromAsciiCodesString (NSString *string)
{
NSArray *components = [string componentsSeparatedByString:#" "];
NSUInteger len = [components count];
char new_str[len+1];
int i;
for (i = 0; i < len; ++i)
new_str[i] = [[components objectAtIndex:i] intValue];
new_str[i] = '\0';
return [NSString stringWithCString:new_str
encoding:NSASCIIStringEncoding];
}
And a simple use of it, with your "Hello" example:
NSString *string = #"72 101 108 108 111";
NSLog(#"%#", TextFromAsciiCodesString(string));
Actually, it's a bit different as your example was "Hell^K" :-)

You can also trying using NSString's enumerateSubstringsInRange:options:usingBlock:.
Usage
NSString * hello = #"72 101 108 108 111";
NSMutableString * result = [NSMutableString string];
[hello enumerateSubstringsInRange:NSMakeRange(0, [data length])
options:NSStringEnumerationByWords
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
[result appendString:[NSString stringWithFormat:#"%c", [substring intValue]]];
}];
NSLog(#"%#", result);

Related

NSString unichar from int

I have an int value which I obtained from the character 爸, which is 29240. I can convert this number to hex, but I have no clue how to write the chinese character out in an NSString with only the int 29240.
Basically, what I did was:
NSString * s = #"爸";
int a = [s characterAtIndex:0];
NSLog(#"%d", a);
What it gave as output was 29240.
However, I don't know how to create an NSString that just contains 爸 from only the int 29240.
I converted 29240 into binary which gave me 7238, but I can't seem to create a method which allows me to input any integer and NSLog the corresponding character.
I can hard code it in, so that I have
char cString[] = "\u7238";
NSData *data = [NSData dataWithBytes:cString length:strlen(cString)];
NSString *string = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
NSLog(#"result string: %#", string);
But I'm not sure how to do it with any int.
Thanks to anyone who can help me!
To create a string from one (or more) Unicode characters use initWithCharacters:
unichar c = 29240;
NSString *string = [[NSString alloc] initWithCharacters:&c length:1];
NSString uses UTF-16 characters internally, so
this works for all characters in the "Basic Multilingual Plane", i.e. all characters up to U+FFFF. The following code works for arbitrary characters:
uint32_t ch = 0x1F60E;
ch = OSSwapHostToLittleInt32(ch); // To make it byte-order safe
NSString *s1 = [[NSString alloc] initWithBytes:&ch length:4 encoding:NSUTF32LittleEndianStringEncoding];
NSLog(#"%#", s1);
// Output: 😎
Try out this code snippet to get you started in the right direction:
NSString *s = #"0123456789";
for (int i = 0; i < [s length]; i++) {
NSLog(#"Value: %d", [s characterAtIndex:i]);
}
Just pass in the character as an integer:
unichar decimal = 12298;
NSString *charStr = [NSString stringWithFormat:#"%C", decimal];

(# ゚Д゚) is a 5-letter-word. But in iOS, [#"(# ゚Д゚)" length] is 7. Why?

(# ゚Д゚) is a 5-letter-word. But in iOS, [#"(# ゚Д゚)" length] is 7.
Why?
I'm using <UITextInput> to modify the text in a UITextField or UITextView. When I make a UITextRange of 5 character length, it can just cover the (# ゚Д゚) . So, why this (# ゚Д゚) looks like a 5-character-word in UITextField and UITextView, but looks like a 7-character-word in NSString???
How can I get the correct length of a string in this case?
1) As many in the comments have already stated, Your string is made of 5 composed character sequences (or character clusters if you prefer). When broken down by unichars as NSString’s length method does you will get a 7 which is the number of unichars it takes to represent your string in memory.
2) Apparently the UITextField and UITextView are handling the strings in a unichar savvy way. Good news, so can you. See #3.
3) You can get the number of composed character sequences by using some of the NSString API which properly deals with composed character sequences. A quick example I baked up, very quickly, is a small NSString category:
#implementation NSString (ComposedCharacterSequences_helper)
-(NSUInteger)numberOfComposedCharacterSequences{
__block NSUInteger count = 0;
[self enumerateSubstringsInRange:NSMakeRange(0, self.length)
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop){
NSLog(#"%#",substring); // Just for fun
count++;
}];
return count;
}
#end
Again this is quick code; but it should get you started. And if you use it like so:
NSString *string = #"(# ゚Д゚)";
NSLog(#"string length %i", string.length);
NSLog(#"composed character count %i", [string numberOfComposedCharacterSequences]);
You will see that you get the desired result.
For an in-depth explanation of the NSString API check out the WWDC 2012 Session 215 Video "Text and Linguistic Analysis"
Both ゚ and Д゚ are represented by a character sequence of two Unicode characters (even when they are visually presented as one). -[NSString length] reports the number of Unicode chars:
The number returned includes the individual characters of composed
character sequences, so you cannot use this method to determine if a
string will be visible when printed or how long it will appear.
If you want to see the byte representation:
#import <Foundation/Foundation.h>
NSString* describeUnicodeCharacters(NSString* str)
{
NSMutableString* codePoints = [NSMutableString string];
for(NSUInteger i = 0; i < [str length]; ++i){
long ch = (long)[str characterAtIndex:i];
[codePoints appendFormat:#"%0.4lX ", ch];
}
return codePoints;
}
int main(int argc, char *argv[]) {
#autoreleasepool {
NSString *s = #" ゚Д゚";
NSLog(#"%ld unicode chars. bytes: %#",
[s length], describeUnicodeCharacters(s));
}
}
The output is: 4 unicode chars. bytes: 0020 FF9F 0414 FF9F.
2) and 3): what NJones said.

How to convert NSString to hexadecimal string of fixed block size

In my application I am converting a NSString to HexString. But I always require a fixed size(16 bytes) hex string e.g. if the length of my hex string is 15 bytes, I want it to be 16 bytes. I know that I can add zeros at the beginning of the hex string, but how to add that because simply adding a "0" is not working while I am converting it back into NSString.
You can try this code....
+ (NSString *) stringToHex:(NSString *)str
{
NSUInteger len = [str length];
unichar *chars = malloc(len * sizeof(unichar));
[str getCharacters:chars];
NSMutableString *hexString = [[NSMutableString alloc] init];
for(NSUInteger i = 0; i &lt len; i++ )
{
// [hexString [NSString stringWithFormat:#"%02x", chars[i]]]; //previous input
[hexString appendFormat:#"%02x", chars[i]]; //EDITED PER COMMENT BELOW
}
free(chars);
return [hexString autorelease];
}
I hope this will help you.
happy coding.

Converting NSString, data type expression, to actual NSData

NSString *string1 = #"<616263>";
I want to make this into NSData *data1 = <616263>;
so that when I
NSString *string2 = [[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding];
NSLog(#"%#", string2);
Result: abc
would come out
p.s.
<616263>, this is data expression of #"abc"
The trick is converting 616263 to abc. Since you are starting with the ASCII representation of the character codes, you need to convert your NSString to an array of bytes (or your original data source to an array instead of saving it as an NSString in the first place).
NSString *string1 = #"616263";
// Make sure that buffer is big enough!
char sourceChars[7];
[string1 getCString:sourceChars maxLength:7 encoding:NSUTF8StringEncoding];
char destBuffer[3];
char charBuffer[3];
// Loop through sourceChars and convert the ASCII character groups to char's
// NOTE: I assume that these are always two character groupings per your example!
for (int index = 0; index < [string1 length]; index = index + 2) {
// Copy the next two digits into charBuffer
strncpy(charBuffer, &sourceChars[index], 2);
charBuffer[2] = '\0';
// convert charBuffer (ie 61) from hex to decimal
destBuffer[index / 2] = strtol(charBuffer, NULL, 16);
}
// destBuffer is properly formatted: init data1 with it.
NSData *data1 = [NSData dataWithBytes:destBuffer length:[string1 length]/2];
// Test
NSString *string2 = [[NSString alloc] initWithData:data1 encoding:NSUTF8StringEncoding];
NSLog(#"%#", string2); // Prints abc

how to remove () charracter

when i convert my array by following method , it adds () charracter.
i want to remove the () how can i do it..
NSMutableArray *rowsToBeDeleted = [[NSMutableArray alloc] init];
NSString *postString =
[NSString stringWithFormat:#"%#",
rowsToBeDeleted];
int index = 0;
for (NSNumber *rowSelected in selectedArray)
{
if ([rowSelected boolValue])
{
profileName = [appDelegate.archivedItemsList objectAtIndex:index];
NSString *res = [NSString stringWithFormat:#"%d",profileName.userID];
[rowsToBeDeleted addObject:res];
}
index++;
}
UPDATE - 1
when i print my array it shows like this
(
70,
71,
72
)
Here's a brief example of deleting the given characters from a string.
NSString *someString = #"(whatever)";
NSCharacterSet *charSet = [NSCharacterSet characterSetWithCharactersInString:#"()"];
NSMutableString *mutableCopy = [NSMutableString stringWithString:someString];
NSRange range;
for (range = [mutableCopy rangeOfCharacterFromSet:charSet];
range.location != NSNotFound;
[mutableCopy deleteCharactersInRange:range],
range = [mutableCopy rangeOfCharacterFromSet:charSet]);
All this does is get a mutable copy of the string, set up a character set with any and all characters to be stripped from the string, and find and remove each instance of those characters from the mutable copy. This might not be the cleanest way to do it (I don't know what the cleanest is) - obviously, you have the option of doing it Ziminji's way as well. Also, I abused a for loop for the hell of it. Anyway, that deletes some characters from a string and is pretty simple.
Try using NSArray’s componentsJoinedByString method to convert your array to a string:
[rowsToBeDeleted componentsJoinedByString:#", "];
The reason you are getting the parenthesis is because you are calling the toString method on the NSArray class. Therefore, it sounds like you just want to substring the resulting string. To do this, you can use a function like the following:
+ (NSString *) extractString: (NSString *)string prefix: (NSString *)prefix suffix: (NSString *)suffix {
int strLength = [string length];
int begIndex = [prefix length];
int endIndex = strLength - (begIndex + [suffix length]);
if (endIndex > 0) {
string = [string substringWithRange: NSMakeRange(begIndex, endIndex)];
}
return string;
}