divide string into characters - objective-c

I have an NSString *titleName which changes according to an if statement. So the length (number of characters) in the string changes. I would like to divide titleName into a MutableArray of separate strings consisting of its individual characters. I would then like to use these separate strings as the text in different UILabels. I am not sure as how to go about this.
Through some research I have tried to create the NSMutable array like this
NSMutableArray *letterArray = substringWithRange:((i = 0);i<[titleName2 length];i++));
but this gives me an error Use of undeclared identifier 'substringWithRange.
Can someone help me.
I decided to use componentsSeparatedByString instead and just created my various strings with a , between each letter. Thanks for anybody's thoughts though.

The code you pasted is not valid objective-C.
To keep the same algorithm you should write something like :
NSMutableArray *letterArray = [NSMutableArray array];
NSUInteger length = [titleName2 length];
for (NSUInteger i = 0; i < length; ++i) {
[letterArray addObject:[titleName2 substringWithRange:NSMakeRange(i, 1)]];
}

It's probably much "cheaper" to hold a C-array of unichar characters that make-up the string. It will also be quicker to create:
NSString *input = #"How now brown cow?";
unichar chars[[input length]];
for (NSInteger i = 0; i < [input length]; i++)
chars[i] = [input characterAtIndex:i];
Alternatively you could use malloc() to create the C-array:
NSString *input = #"How now brown cow?";
unichar *chars = (unichar *)malloc([input length]);
for (NSInteger i = 0; i < [input length]; i++)
chars[i] = [input characterAtIndex:i];
and then use free(), later, to, err, free the memory:
free(chars);
Cheaper still, would be to not split-up the string at all...

Try this below code
NSMutableArray *letterArray = [NSMutableArray array];
for (int i = 0;i<[titleName2 length];i++)
{
[letterArray addObject: [titleName2 substringWithRange:NSMakeRange(i,1)]];
}
DLog(#"%#", letterArray);
Other option to get characters of string
NSMutableArray *letterArray = [NSMutableArray array];
for (int i=0; i < [titleName2 length]; i++)
{
[letterArray addObject:[NSString stringWithFormat:#"%c", [titleName2 characterAtIndex:i]]];
}
DLog(#"characters - %#", letterArray);

Related

How can I convert an NSRange to a delimited string of its values?

Given an NSRange, such as:
NSRange range = NSMakeRange(1, 22);
What's the best way to convert it to a comma-separated string of its values?
#"1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22"
The best I could come up with was to iterate over the range and insert its values into an NSArray, and then call -componentsJoinedByString: on the array. But that seems pretty wasteful, not to mention inelegant. Is there no better way?
My version using an array:
NSMutableArray *vals = [NSMutableArray arrayWithCapacity:range.length];
for (NSUInteger i = range.location; i < range.length; i++){
[vals addObject:#(i)];
}
NSString *string = [vals componentsJoinedByString:#","];
You can use NSIndexSet with indexSetWithIndexesInRange: to generate a list of values, and then iterate through them with enumerateIndexesUsingBlock:. E.g.
NSIndexSet *indexSet = [NSIndexSet indexSetWithIndexesInRange:range];
NSMutableArray *indices = [NSMutableArray array];
[indexSet enumerateIndexesUsingBlock:^(NSUInteger i, BOOL *stop) {
[indices addObject:#(i)];
}];
NSString *string = [indices componentsJoinedByString:","];
NSMutableString *string=[#"" mutableCopy];
for (int i = range.location; i<range.length-1; i++){
[string appendFormat:#"%d,", i];
}
[string appendString#"%d", range.length-1];
If you want to hide the code, you can turn it into a function that would take the range and turn it into a string, that way this is hidden from your code. Or maybe turn it into a NSString class method, something like
[NSString stringWithRangeValues:range];
That would be like:
+ (NSString *)stringWithRangeValues:(NSRange)range{
NSMutableString *string=[#"" mutableCopy];
for (int i = range.location; i<range.lenght-1; i++){
[string appendFormat:#"%d,", i];
}
[string appendString#"%d", range.length-1];
return [NSString stringWithString:string];
}

string tokenizer in ios

I like to tokenize a string to characters and store the tokens in a string array. I am trying to use following code which is not working as I am using C notation to access the array. What needs to be changed in place of travel path[i]?
NSArray *tokanizedTravelPath= [[NSArray alloc]init];
for (int i=0; [travelPath length]; i++) {
tokanizedTravelPath[i]= [travelPath characterAtIndex:i];
You can't store unichars in an NSArray*. What exactly are you trying to accomplish? An NSString* is already a great representation for a collection of unichars, and you already have one of those.
You need a NSMutableArray to set every element of the array (otherwise you can't change its objects).Also, you can only insert objects in the array, so you can:
- Insert a NSString containing the character;
- Use a C-style array instead.
This is how to do with the NSMutableArray:
NSMutableArray *tokanizedTravelPath= [[NSMutableArray alloc]init];
for (int i=0; i<[travelPath length]; i++)
{
[tokanizedTravelPath insertObject: [NSString stringWithFormat: #"%c", [travelPath characterAtIndex:i]] atIndex: i];
}
I count 3 errors in your code, I explain them at the end of my answer.
First I want to show you a better approach to split a sting into it characters.
While I agree with Kevin that an NSString is a great representation of unicode characters already, you can use this block-based code to split it into substrings and save it to an array.
Form the docs:
enumerateSubstringsInRange:options:usingBlock:
Enumerates the
substrings of the specified type in the specified range of the string.
NSString *hwlloWord = #"Hello World";
NSMutableArray *charArray = [NSMutableArray array];
[hwlloWord enumerateSubstringsInRange:NSMakeRange(0, [hwlloWord length])
options:NSStringEnumerationByComposedCharacterSequences
usingBlock:^(NSString *substring,
NSRange substringRange,
NSRange enclosingRange,
BOOL *stop)
{
[charArray addObject:substring];
}];
NSLog(#"%#", charArray);
Output:
(
H,
e,
l,
l,
o,
" ",
W,
o,
r,
l,
d
)
But actually your problems are of another nature:
An NSArray is immutable. Once instantiated, it cannot be altered. For mutable array, you use the NSArray subclass NSMutableArray.
Also, characterAtIndex does not return an object, but a primitive type — but those can't be saved to an NSArray. You have to wrap it into an NSString or some other representation.
You could use substringWithRange instead.
NSMutableArray *tokanizedTravelPath= [NSMutableArray array];
for (int i=0; i < [hwlloWord length]; ++i) {
NSLog(#"%#",[hwlloWord substringWithRange:NSMakeRange(i, 1)]);
[tokanizedTravelPath addObject:[hwlloWord substringWithRange:NSMakeRange(i, 1)]];
}
Also your for-loop is wrong, the for-loop condition is not correct. it must be for (int i=0; i < [travelPath length]; i++)

XOR'ing two hex values stored as an NSString?

here is yet another silly question from me!
NSString *hex1 = #"50be4f3de4";
NSString *hex2 = #"30bf69a299";
/* some stuff like result = hex1^hex2; */
NSString *result = #"6001269f7d";
I have a hex value as a string, stored in two diff. variables. i need to Xor them and the result should be in another string variables?
i tried them by converting string --> NSData --> bytes array --> xor'ing them ...but i have no success.....
thank you in advance...
You have to convert every character to Base16(for hexadecimal) format first.Then you should proceed with XORing those characters.You can use the strtol() function to achieve this purpose.
NSString *hex1 = #"50be4f3de4";
NSString *hex2 = #"30bf69a299";
NSMutableArray *hexArray1 = [self splitStringIntoChars:hex1];
NSMutableArray *hexArray2 = [self splitStringIntoChars:hex2];
NSMutableString *str = [NSMutableString new];
for (int i=0; i<[hexArray1 count]; i++ )
{
/*Convert to base 16*/
int a=(unsigned char)strtol([[hexArray1 objectAtIndex:i] UTF8String], NULL, 16);
int b=(unsigned char)strtol([[hexArray2 objectAtIndex:i] UTF8String], NULL, 16);
char encrypted = a ^ b;
NSLog(#"%x",encrypted);
[str appendFormat:#"%x",encrypted];
}
NSLog(#"%#",str);
Utility method that i used to split characters of the string
-(NSMutableArray*)splitStringIntoChars:(NSString*)argStr{
NSMutableArray *characters = [[NSMutableArray alloc]
initWithCapacity:[argStr length]];
for (int i=0; i < [argStr length]; i++)
{
NSString *ichar = [NSString stringWithFormat:#"%c", [argStr characterAtIndex:i ]];
[characters addObject:ichar];
}
return characters;
}
Hope it helps!!

Problem with NSString and NSRange

I'm having a rather annoying problem here. See, I'm trying to break up a string that I get into individual characters and symbols. The string is always in the form of an equation, like "3x+4" or "x/7+5". I need to separate the string into an array of individual strings. For example, if I had the first equation, I would want to have an NSMutableArray that has "3", "x", "+", and "4". Here is the section of code that I use:
NSMutableArray* list = [[NSMutableArray alloc] initWithCapacity:10];
for (int i = 0; i < [self.equationToGuess length]; i++) {
NSRange range = {i, i};
NSString* string= [[NSString alloc] initWithString:[self.equationToGuess substringWithRange:range]];
[list addObject:string];
}
I've made sure to check if self.equationToGuess always contains an equation using the debugger, and it does. list is also able to get some of the objects, but the problem is that it just puts the last two characters in one shelf on the list. So if I have that "3x+4" equation, this chunk of code puts "3", "x", and "+4" into the code, and then it crashes because it goes beyond the length of the string. Does anyone know how to fix this?
The two values in NSRange are not the starting and ending index. Rather, the first is the starting index and the second is the length of the range. So instead you want your range to be
NSRange range = NSMakeRange(i, 1);
Let's do this with a bit more panache:
NSInteger numberOfCharacters = [self.equationToGuess length];
NSMutableArray *characterArray = [[NSMutableArray alloc] initWithCapacity:numberOfCharacters];
for (NSUInteger idx = 0; idx < numberOfCharacters; idx++) {
NSRange range = NSMakeRange(idx, 1);
[characterArray addObject:[self.equationToGuess substringWithRange:range]];
}
Edit
After a hearty helping of humble pie - this is still not the best way to do it: if your equation has multi-digit coefficients, they will be split up. Have you considered using NSScanner to split the string up instead?
you could also use an alternative solution by getting characters from you string , for that you will have to use the below function of NSString.
- (unichar)characterAtIndex:(NSUInteger)index
.
NSMutableArray* list = [[NSMutableArray alloc] initWithCapacity:10];
NSString* string;
for (int i = 0; i < [self.equationToGuess length]; i++)
{
string = [[NSString alloc] initWithFormat:#"%c",[self.equationToGuess characterAtIndex:i]];
[list addObject:string];
[string release];
string = nil ;
}
NSInteger numberOfCharacters = [self.equationToGuess length];
NSMutableArray *characterArray = [[NSMutableArray alloc] initWithCapacity:numberOfCharacters];
for (NSUInteger idx = 0; idx < numberOfCharacters; idx++) {
[characterArray addObject:[NSString stringWithFormat:#"%c", [self.equationToGuess characterAtIndex:idx]]];
}

Objective-C Iterating through an NSString to get characters

I have this function:
void myFunc(NSString* data) {
NSMutableArray *instrs = [[NSMutableArray alloc] initWithCapacity:[data length]];
for (int i=0; i < [data length]; i++) {
unichar c = [data characterAtIndex:i];
[instrs addObject:c];
}
NSEnumerator *e = [instrs objectEnumerator];
id inst;
while (inst = [e nextObject]) {
NSLog("%i\n", inst);
}
}
I think it fails at [instrs addObject:c]. It's purpose is to iterate through the hexadecimal numbers of an NSString. What causes this code to fail?
A unichar is not an object; it's an integer type.
NSMutableArray can only hold objects.
If you really want to put it into an NSMutableArray, you could wrap the integer value in an NSNumber object: [instrs addObject:[NSNumber numberWithInt:c]];
But, what's the point of stuffing the values into an array in the first place? You know how to iterate through the string and get the characters, why put them into an array just to iterate through them again?
Also note that:
the "%i" NSLog format expects an integer; you can't pass it an object
for hexadecimal output, you want "%x", not "%i"
If the function is only meant to display the characters as hexadecimal values, you could use:
void myFunc(NSString* data)
{
NSUInteger len = [data length];
unichar *buffer = calloc(len, sizeof(unichar));
if (!buffer) return;
[data getCharacters:buffer range:NSMakeRange(0, len)];
for (NSUInteger i = 0; i < len; i++)
NSLog(#"%04x", (unsigned) buffer[i]);
free(buffer);
}
This is just a little bit more efficient than your approach (also, in your approach you never release the instrs array, so it will leak in a non-garbage-collected environment).
If the string contains hexadecimal numbers, then you will want to repeatedly use an NSScanner's scanHexInt: method until it returns NO.
void myFunc(NSString* data)
{
NSScanner *scanner = [[NSScanner alloc] initWithString:data];
unsigned number;
while ([scanner scanHexInt:&number])
NSLog(#"%u", number);
[scanner release];
}