Objective-C: Splitting a word into an array of characters - objective-c

Sorry for the rather simple question but I'm pretty new to objective-c and can't seem to find a solution to my problem that actually works with what i'm trying to do.
Essentially, I have a NSString containing the a random word.
For example:
NSString *word = #"Characters";
I then want to take this and split it into an array consisting of the characters so that I can index each of them:
[0] C
[1] H
[2] A
etc
It's not really important if after they're split if they're put into a NSString or an Array, as long as I can separate the string into each off the individual characters then index them.
Also for clarification, the word isn't hard coded it's randomly generated every time my program runs and pulled from a word list.
Any help is appreciated!

There's no reason to do this. Internally, the string already is an array of characters, and you can access the individual characters by index...
[word characterAtIndex:2] // returns 'a'

Update Swift 4+
Default you have a string
let string = "Characters"
so, all you need to do is...
for i:Int in 0..< string.count {
let char = NSString(format: "%c", (string as NSString).character(at: i))
print(char) //Optionally you can convert using 'char as String'
}
Note:- this is the update for this answer

Related

What does stringWithUTF8String do?

So I have done some searching around so that I could see what it was I was doing with my code, and I couldn't find any answers as to what this very one specific line of code does.
NSString* name = [NSString stringWithUTF8String:countryName];
I know what the rest does (I only had to google how to do this part), it is supposed to take my char* (countryName) and turn it into an NSString so later on I can compare it with the
isEqualToString:
thing. I would just like to know what the following is actually doing to the char, and what does the UTF8String even mean?
I have barely any Objective C programming experience so any feedback is helpful :D
you are not totally right.
this method
Returns a string created by copying the data from a given C array of UTF8-encoded bytes.
so, UTF-8 string here is just a C array of bytes.
Check the documentation here.
It doesn't do anything to the char * string. It's just the input to the method. stringWithUTF8String takes a C-style string (in UTF-8 encoding), and creates an NSString using it as a template.

NSString and NSMutableString concatenation

I have three strings (a NSString, a NSMutableString, and another NSString) which I need to concatenate into a mutable string, in that order, to display as the source for a UIWebView. Comming from a PHP/JavaScript/HTML background, my knowledge of concatenation is pretty much this:
var concatenatedString = string1 + string2 + string3;
I presume that sort of thing won't work in Objective-C, so I'm wondering how to go about pulling them all together properly.
To give a bit of setting for this, the first string (NSString) is the header and canvas element of a web page, the second string (NSMutableString) is javascript from a text field that the user can define to manipulate the canvas element, and the third string (NSString) is the end tags of the web page.
Also, rather than initially creating the NSMutableString, should I just referance the UITextView.text to the get the user's text when concatenating the whole thing, or should I pull the text from the UITextView first?
NSMutableString *concatenatedString = [[NSString stringWithFormat:#"%#%#%#", string1, string2, string3] mutableCopy];
The other two answers are correct in that they answer the question as you asked it. But by your description of what you want to do there is a much easier way. Use a format.
Assuming string1 and string3 will always be the same and only string2 will change,which is what it sounds like you are doing you can write something like this.
static NSString *formatString = #"String1Text%#String3Text";
NSString *completeString = [NSString stringWithFormat:formatString,self.myTextFieldName.text];
NSLog(#"%#",completeString);
The %# in the format says to insert the description of the object following the format.(The description of an NSString is the stringValue.)
Assuming you have a UITextField named myTextFieldName, that currently contains the text 'String2Text' Then this will be the output:
'String1TextString2TextString3Text'
In this way you only create 1 instance of an NSString format for the whole class no matter how many times you call this code.
To me it sounds like you don't need a mutable string at all. Feel free to leave a comment if I misunderstood anything.
Response to comment:
I'm not sure how you are implementing 'moves to test it out again' but, let's say you have a button named 'testJavaScript'. The IBAction method connected to that button would have the first two lines in it. So each time you pushed the button it would make a new formatted NSString filled with the current contents of the textfield. Once this string was formed it could not be changed. But it won't matter since next time it will make another.
NSString *concatenatedString = [string1 stringByAppendingFormat:#"%#%#", string2, string3];
You can make the resulting string mutable (if you really need to) by adding mutableCopy as shown in the answer by #Vinnie.

parse strings separated by 2 elements

On Mac OS X, in Ojective-C, I wanted to know if anyone could give me some pointers as to how I could parse strings contained between "x" and "y".
My current code only enables me to separate the strings separated by one componennt :
NSArray * allLines = [theDataObject componentsSeparatedByString:#"word-1"];
Ideally, I would like to isolate the strings contained between #"word-1" and #"word-2".
Could anyone help please? Thanks in advance!
Check the documentation for NSScanner. The methods you want are -scanUpToString:intoString: and -scanString:intoString:
NSString *str = [theDataObject stringByReplacingOccurencesOfString:#"word-2" withString:#"word-1"];
NSArray *allLines = [str componetnsSeperatedByString:#"word-1"];
You don't care whether its word-1 or word-2 as those do not come back in the array anyways.

Help in padding numerical strings

I am trying to generate a numerical string by padding the number with zeroes to the left.
0 would become 00000
1 would become 00001
10 would become 00010
I want to create five character NSString by padding the number with zeroes.
I read this Create NSString by repeating another string a given number of times but the output is an NSMutableString.
How can I implement this algorithm with the output as an NSString?
Best regards.
You can accomplish this by calling
[NSString stringWithFormat:#"%05d", [theNumber intValue]];
where theNumber is the NSString containing the number you want to format.
For further reading, you may want to look at Apple's string formatting guide or the Wikipedia entry for printf.
One quick & simple way to do it:
unsigned int num = 10; // example value
NSString *immutable = [NSString stringWithFormat:#"%.5u", num];
If you actually really want to use the long-winded approach from the example you read, you can send a “copy” message to a mutable string to get an immutable copy. This holds for all mutable types.

Xcode - EXEC_BAD_ACCESS when concatenting a large string

I'm getting a EXEC_BAD_ACCESS when concatenting a large string.
I've read from a feed and to create my webview I build up my string like:
NSString *pageData = #"<h1>header</h1>";
pageData = [pageData stringByAppendingFormat#"<p>"];
pageData = [pageData stringByAppendingFormat#"self.bodyText"];
pageData = [pageData stringByAppendingFormat#"</p>"];
etc
The problem I've got is self.bodytext is 21,089 characters with spaces when I do a count on word.
Is there a better method for doing this?
Thanks
You would definitely want to use NSMutableString for something like this:
NSMutableString * pageData = [NSMutableString stringWithCapacity:0];
[pageData appendFormat:#"<h1>header</h1>"];
[pageData appendFormat:#"<p>"];
...
NSMutableString is designed for this kind of sequential concatenation, where the basic NSString class is really not meant to be used in this manner. Your original code would actually allocate a new NSString every time you called stringByAppendFormat:, and then procede to copy into it all of the thousands of characters you had already appended. This could easily result in an out of memory error, since the size of the temporary strings would be growing exponentially as you add more and more calls.
Using NSMutableString will not re-copy all of the string data when you call appendFormat:, since the mutable string maintains an internal buffer and simply tacks new strings on to the end of it. Depending on the size of your string, you may want to reserve a huge chunk of memory ahead of time (use a meaningful number for the ...WithCapacity: argument). But there is no need to go that route unless you actually run into performance issues.
There are a few problems with your sample code:
You should be using a NSMutableString to build up an output string by appending multiple parts. NSString is an immutable class which means that each time you call stringByAppendingFormat: you are incurring the overhead of creating an additional new NSString object which will need to be collected and released by the autorelease pool.
NSMutableString * pageData = [NSMutableString stringWithCapacity:0];
You should use appendString: on your NSMutableString to append content, instead of stringByAppendingFormat: or appendFormat:. The format methods are intended for creating new strings based on a format specifier which includes special fields as placeholders. See Formatting String Objects for more details. When you're using stringByAppendingFormat: with just a literal string like your code has, you are incurring the overhead of parsing the string for the non-existant placeholders, and more importantly, if the string happens to have a placeholder (or something that looks like one) in it, you'll end up with the EXEC_BAD_ACCESS crash that you are getting. Most likely this happening when your bodyText is appended. Thus if you simply want to append a '' to your NSMutableString do something like this:
[pageData appendString:#"<p>"];
If you want to append the contents of the self.bodyText property to the string, you shouldn't put the name of the property inside of a string literal (i.e. #"self.bodyText" is the literal string "self.bodyText", not the contents of the property. Try:
[pageData appendString:self.bodyText];
As an example, you could actually combine all three lines of your sample code by using a format specification:
pageData = [pageData stringByAppendingFormat:#"<p>%#</p>", self.bodyText];
In the format specification %# is a placeholder that means insert the result of sending the description or descriptionWithLocale: message to the object. For an NSString this is simply the contents of the string.
I doubt the length of the string is really a problem. A 50,000-character string is only about 100 KB. But you want to be very careful about using format strings. If your string contains something that looks like a formatting specifier, there had better be a corresponding argument or you'll get garbage if you're lucky and a crash if you're not. I suspect this is the error, since there is no other obvious problem from your description. Be careful about what you put in there, and avoid ever putting dynamic text in a format string — just put a %# in the format string and pass the dynamic text as an argument.
Use appendString: instead of appendFormat: when dealing with arbitrary strings.
pageData = [pageData stringByAppendingString:#"<p>"];
pageData = [pageData stringByAppendingString:#"self.bodyText"];
pageData = [pageData stringByAppendingString:#"</p>"];
or do not use an arbitrary string as the format:
pageData = [pageData stringByAppendingFormat:#"<p>%#</p>" , #"self.bodyText"];
If you are building the string up in pieces, use NSMutableString instead of several stringBy calls.
Remember that % is a special character for formatted strings and for url escapes, so if bodyText contains a url it could easily cause a crash.