How to get a single NSString character from an NSString - objective-c

I want to get a character from somewhere inside an NSString. I want the result to be an NSString.
This is the code I use to get a single character at index it:
[[s substringToIndex:i] substringToIndex:1]
Is there a better way to do it?

This will also retrieve a character at index i as an NSString, and you're only using an NSRange struct rather than an extra NSString.
NSString * newString = [s substringWithRange:NSMakeRange(i, 1)];

If you just want to get one character from an a NSString, you can try this.
- (unichar)characterAtIndex:(NSUInteger)index;
Used like so:
NSString *originalString = #"hello";
int index = 2;
NSString *theCharacter = [NSString stringWithFormat:#"%c", [originalString characterAtIndex:index-1]];
//returns "e".

Your suggestion only works for simple characters like ASCII. NSStrings store unicode and if your character is several unichars long then you could end up with gibberish. Use
- (NSRange)rangeOfComposedCharacterSequenceAtIndex:(NSUInteger)index;
if you want to determine how many unichars your character is. I use this to step through my strings to determine where the character borders occur.
Being fully unicode able is a bit of work but depends on what languages you use. I see a lot of asian text so most characters spill over from one space and so it's work that I need to do.

NSMutableString *myString=[NSMutableString stringWithFormat:#"Malayalam"];
NSMutableString *revString=#"";
for (int i=0; i<myString.length; i++) {
revString=[NSMutableString stringWithFormat:#"%c%#",[myString characterAtIndex:i],revString];
}
NSLog(#"%#",revString);

Related

Get Unicode point of NSString and put that into another NSString

What's the easiest way to get the Unicode value from an NSString? For example,
NSString *str = "A";
NSString *hex;
Now, I want to set the value of hex to the Unicode value of str (i.e. 0041)... How would I go about doing that?
The unichar type is defined to be a 16-bit unicode value (eg, as indirectly documented in the description of the %C specifier), and you can get a unichar from a given position in an NSString using characterAtIndex:, or use getCharacters:range: if you want to fill a C array of unichars from the NSString more quickly than by querying them one by one.
NSUTF32StringEncoding is also a valid string encoding, as are a couple of endian-specific variants, in case you want to be absolutely future proof. You'd get a C array of those using the much more longwinded getBytes:maxLength:usedLength:encoding:options:range:remainingRange:.
EDIT: so, e.g.
NSString *str = #"A";
NSLog(#"16-bit unicode values are:");
for(int index = 0; index < [str length]; index++)
NSLog(#"%04x", [str characterAtIndex:index]);
You can use
NSData * u = [str dataUsingEncoding:NSUnicodeStringEncoding];
NSString *hex = [u description];
You may replace NSUnicodeStringEncoding by NSUTF8StringEncoding, NSUTF16StringEncoding (the same as NSUnicodeStringEncoding) or NSUTF32StringEncoding, or many other values.
See here
for more

Split NSString into words, then rejoin it into original form

I am splitting an NSString like this: (filter string is an nsstring)
seperatorSet = [NSMutableCharacterSet whitespaceAndNewlineCharacterSet];
[seperatorSet formUnionWithCharacterSet:[NSCharacterSet punctuationCharacterSet]];
NSMutableArray *words = [[filterString componentsSeparatedByCharactersInSet:seperatorSet] mutableCopy];
I want to put words back into the form of filter string with the original punctuation and spacing. The reason I want to do this is I want to change some words and put it back together as it was originally.
A more robust way to split by words is to use string enumeration. A space is not always the delimiter and not all languages delimit spaces anyway (e.g. Japanese).
NSString * string = #" \n word1! word2,%$?'/word3.word4 ";
[string enumerateSubstringsInRange:NSMakeRange(0, string.length)
options:NSStringEnumerationByWords
usingBlock:
^(NSString *substring, NSRange substringRange, NSRange enclosingRange, BOOL *stop) {
NSLog(#"Substring: '%#'", substring);
}];
// Logs:
// Substring: 'word1'
// Substring: 'word2'
// Substring: 'word3'
// Substring: 'word4'
NSString *myString = #"Foo Bar Blah B..";
NSArray *myWords = [myString componentsSeparatedByCharactersInSet:
[NSCharacterSet characterSetWithCharactersInString:#" "]
];
NSString* string = [myWords componentsJoinedByString: #" "];
NSLog(#"%#",string);
Since you eliminate the original punctuation, there's no way to turn it back automatically.
The only way is not to use componentsSeparatedByCharactersInSet.
An alternative solution may be to iterate through the string and, for each char, check if it belongs to your character set.
If yes, add the char to a list and the substring to another list (you may use NSMutableArray class).
This way, for example, you know that the punctuation char between the first and the second substring is the first character in your list of separators.
You can use the pathArray componentsJoinedByString: method of the array class to rejoin the words:
NSString *orig = [words pathArray componentsJoinedByString:#" "];
How are you determining which words need to be replaced? Instead of breaking it apart in the first place, perhaps using -stringByReplacingOccurrencesOfString:withString:options:range: would be more suitable.
My guess is you may not be using the best API. If you're really worried about words, you should be using a word-based API. I'm a bit hazy on whether that would be NSDataDetector or something else. (I believe NSRegularExpression can deal with word boundaries in a smarter way.)
If you are using Mac OS X 10.7+ or iOS 4+ you can use NSRegularExpression, The pattern to replace a word is: "\b word \b" - (no spaces around word) \b matches a word boundary. Look at methods replaceMatchesInString:options:range:withTemplate: and stringByReplacingMatchesInString:options:range:withTemplate:.
Under 10.6 pr earlier if you wish to use regular expressions you can wrap the regcomp/regexec C-based functions, they support word boundaries as well. However you may prefer to use one of the other Cocoa options mentioned in other answers for this simple case.

Random uppercase - lowercase

I'd like to let a string change letters to lowercase or uppercase randomly(in Xcode).
for example: "example" to "ExaMpLe" or "eXAMPle" or ExAmPlE" or something else like this randomly..
hot can i solve this?
thanks
You could either use the -uppercaseString and -lowercaseString methods on substrings, or use the toupper() and tolower() functions on characters. There's no way to simply filter a string; you'll want to use either an NSMutableString or a C array of characters.
See this question for how to get a random boolean value, which you can use to decide whether a character should be uppercase or lowercase.
NSString has both a lowercaseString and uppercaseString method. You can iterate over the characters in a string as a sequence of substrings, using some random source to call the appropriate lower/upper case on each of them, collecting the result. Something like...
NSMutableString result = [NSMutableString string];
for (NSUInteger i = 0; i < [myString length]; i++)
{
NSString *substring = [myString substringWithRange:NSMakeRange(i, 1)];
[result appendString:(rand() % 2) ? [substring lowercaseString]
: [substring uppercaseString]];
}
You may prefer a better source of entropy than rand, but it'll do for an example (don't forget to seed it if you use this case as is). If the strings are large, you can do it in-place on an NSMutableString.
You could break the word into an array of letters, and loop over this using a random number to determining case, after looping the array, simply stick the letters back together using NSMutableString.
NSString had a uppercaseString and lowercaseString methods you can use.

\n does not skip to next line in NSString

NSMutableString *a = #"Hi";
NSMutableString *b =[a stringByAppendingString:#"\n\n Hi Again"];
The above doesn't give an error but does not put "Hi Again" on the next line. Why?
EDIT2
I realised after posting, that the OP had NSString in the title but put NSMutableString in the code. I have submitted an edit to change the NSMutableString to NSString.
I will leave this as it still maybe helpful.
Well I am surprised that does not give an error, because you are giving a NSMutableString a NSString.
You need to read the Documentation on NSMutableStrings.
to give you an idea
//non mutable strings
NSString *shortGreetingString = #"Hi";
NSString *longGreetingString = #"Hi Again";
/*mutable string - is created and given a character capacity The number of characters indicated by capacity is simply a hint to increase the efficiency of data storage. The value does not limit the length of the string
*/
NSMutableString *mutableString= [NSMutableString stringWithCapacity:15];
/*The mutableString, now uses an appendFormat to construct the string
each %# in the Parameters for the appendFormat is a place holder for values of NSStrings
listed in the order you want after the comma.
Any other charactars will be included in the construction, in this case the new lines.
*/
[mutableString appendFormat:#"%#\n\n%#",shortGreetingString,longGreetingString];
NSLog (#"mutableString = %#" ,mutableString);
[pool drain];
I think this might help you. You'd rather to use '\r' instead of '\n'
I also had a similar problem and found \n works in LLDB but not in GDB
Try using NSString. You could use:
NSString *a = [NSString stringWithFormat:#"%#\n\n%#", #"Hi", #"Hello again"]
If your string is going in a UIView (e.g a UILabel), you also need to set the number of lines to 0
myView.numberOfLines=0;

How do I split an NSString by each character in the string?

I have the following code, which works as I expect. What I would like to know if there is an accepted Cocoa way of splitting a string into an array with each character of the string as an object in an array?
- (NSString *)doStuffWithString:(NSString *)string {
NSMutableArray *stringBuffer = [NSMutableArray arrayWithCapacity:[string length]];
for (int i = 0; i < [string length]; i++) {
[stringBuffer addObject:[NSString stringWithFormat:#"%C", [string characterAtIndex:i]]];
}
// doing stuff with the array
return [stringBuffer componentsJoinedByString:#""];
}
As a string is already an array of characters, that seems, ... redundant.
If you really need an NSArray of NSStrings of one character each, I think your way of creating it is OK.
But it appears questionable that your purpose cannot be done in a more readable, safe (and performance-optimized) way. One thing especially seem dangerous to me: Splitting strings into unicode characters is (most of the time) not doing what you might expect. There are characters that are composed of more than one unicode code point. and there are unicode code points that really are more than one character. Unless you know about these (or can guarantee that your input does not contain arbitrary strings) you shouldn’t poke around in unicode strings on the character level.