Check if all characters are uppercase in string - Obj C - objective-c

I know I can check if a string contains uppercase letters but is there some built in function in Objective-C to check if all characters are uppercase letters? I want to avoid looping through each character to see if it contains a lowercase letter and then break out of the loop if it contains one as this takes up more memory and takes more time. Time is a constraint as I have to process thousands of strings.

An alternative approach that might appeal given your concerns: Use NSString's rangeOfCharactersFromSet: passing it NSCharacterSet's lowercaseLetterCharacterSet. If this finds anything then the string isn't all uppercase. It's a single line expression like the other current answers, but doesn't involve creating an uppercase copy of the string and works for all Unicode letters.

try this
NSString * myString;
[myString.uppercaseString isEqualToString:myString];

[your_string.uppercaseString isEqualToString:your_string];
If you need to process a lot of strings, especially long string may be following code will be faster
// In case you need process a lo of strings this set should be initialized before loop!
NSCharacterSet *set = [NSCharacterSet lowercaseLetterCharacterSet];
// check for allowed characters
BOOL isValid = ([string rangeOfCharacterFromSet:set].location == NSNotFound);

#implementation NSString (uppercaseOnly)
- (BOOL) allUpperCase {
return [self rangeOfCharacterFromSet:[[NSCharacterSet upperCaseLetterCharacterSet] invertedSet]].location == NSNotFound;
}

Related

Replacing character within cstring - getting bad access

Is it possible to replace a character from a c string after converting it from NSString via the UTF8string method?
For example take the code below. It is to format a string with particular rule.
- (NSString *)formatString:(NSString *)input {
if (input.length==0) {
return #"";
}
//code to determine rule
....
....
// substitute output format with input characters
if (rule) {
input = [input substringFromIndex:prefix.length];
char *string = (char *)[rule UTF8String];
int repCount = 0;
for (int i=0; i<rule.length; i++) {
if (string[i] == '#') {
if (repCount < input.length)
string[i] = [input characterAtIndex:repCount++];//bad access
else
string[i] = ' ';
}
}
NSMutableString *output = [NSMutableString stringWithCString:string encoding:NSUTF8StringEncoding];
...
... //do something with the output
return output;
} else {
return input;
}
}
Initially string[0] has '#' and it should get replaced with the character in the input. This is not happening.
In a word, NO. That buffer doesn't belong to you so leave it alone.
A couple of issues:
You are casting UTF8String, which returns a const char *, to char *. UTF8String is, by definition, returning a read-only string and you should use it as such. (You really should use casts sparingly, if at all. Certainly never use casts to override const qualifiers for variables.)
If you want to perform this C-string manipulation, you have to copy the string to your own buffer. For example, use getCString or getCharacters methods (but only after you've created a buffer to receive them, and remember to add a character for the NULL terminator).
By the way, you're also returning characterAtIndex, which is a unichar (which can be larger than 8-bits), and using it in your char * buffer (8-bits per character). I'd be wary about mixing and matching those without being very careful. It is best to pick one and stick with it (and unichar offers a little more tolerance for those non-8-bit characters).
Perhaps you check for this earlier, but you're setting string to be those characters after the prefix, and then proceed to check the next rule.length number of characters. But, as far as I can tell, you have no assurances that string actually has that many characters left in it. You should test for that, or else that will also cause problems.
Personally, I'd retire this whole C-string algorithm and employ the appropriate NSString and/or NSMutableString methods to do whatever replacement you wanted, e.g. stringByReplacingCharactersInRange, stringByReplacingOccurrencesOfString, or the equivalent NSMutableString methods, replaceCharactersInRange or replaceOccurrencesOfString.

Search exact word in NSString

I need to find a word or several words. With this method, however, I find also piece of word.
NSString *searchString = [NSString stringWithFormat:#"%#",searchField.text];
NSRange range = [textString rangeOfString : searchString];
if (range.location != NSNotFound) {
NSLog(#"textString = %#", textString);
}
I need the word / words exact
How can I do?
Thank you!
There are various ways of parsing/finding sub-strings in NSString:
NSString itself
NSRegularExpression. This would probably better suit your needs since you can tackle the scenario of surrounding white-spaces around words. Thus is won't return the cat from catapult when searching for cat.
NSScanner (most likely overkill for you needs)
... and they, of course, each have their PROs and CONs.
NSString has 9 methods grouped under "Finding Characters and Substrings". Methods such as:
-rangeOfString:
Finds and returns the range of the first occurrence of a given string within the receiver.
NSRegularExpression has 5 methods grouped under "Searching Strings Using Regular Expressions". Methods such as:
-numberOfMatchesInString: options: range:
Returns the number of matches of the regular expression within the specified range of the string.
It might also be useful to know about NSScanner, but this class would be more useful if you're parsing the string than simply looking for sub-parts.
What happens if you add a space at the end of the search string, like so:
NSString *searchString = [NSString stringWithFormat:#"%# ",searchField.text];
If the string from searchField.text already ends with a space, you would have to remove it.
This is not a perfect solution yet, for example you would not find the search string if it is at the end of a sentence. Instead what you could do is not adding the whitespace character, but instead look at the character after the hit and make sure that it is not a letter. For this, take a look at the class NSCharacterSet:
NSCharacterSet * letters = [NSCharacterSet letterCharacterSet];
if (![letters characterIsMember:[textString characterAtIndex:(range.location+searchString.length)]]) {
...
}

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.

Get longest word from a list of words

Is there a quick method that gets the largest word from an array of words?
NSMutableArray wordlist
Something like the following should do the trick:
NSString *longest = nil;
for(NSString *str in wordlist) {
if (longest == nil || [str length] > [longest length]) {
longest = str;
}
}
I'm not aware of any simpler method.
You could use something like this example to sort an Array (but instead of the 'quality' sort in the example use a length sort on your strings) and then the longest string will be either at the top or at the end (depending on your sorting).
I don't know any objective C myself, but my solution would be to keep an integer 'longest' and a string 'longestWord' and initialise it to 0 and "". Then loop over the list and check if the current word is longer then the 'longest' value. If it is, store the new length and the current word. At the end of the loop, you have the longest word stored in the 'longestWord' variable.
Hope this helps

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.