Objective C: Compare Array Element to String - iphone

Greetings,
I'm trying to simply compare a NSString to an NSArray.
Here is my code:
NSString *username=uname.text;
NSString *regex=#"^[a-zA-Z0-9-_.]{3,20}$";
NSArray *matchArray=nil;
matchArray=[username componentsMatchedByRegex:regex];
if(matchArray[0] == "asdf"){ //this line causes the problem!
NSLog(#"matchArray %#",matchArray);
}
I get an "invalid operands to binary ==" error.
How can I compare the string?
Many thanks in advance,

You are trying to compare an NSString to a C string (char *), which is wrong. matchArray is an NSArray so you cannot treat it as a C array either, you have to use its objectAtIndex: method and pass in the index.
Use this instead:
if ([[matchArray objectAtIndex:0] isEqualToString:#"asdf"]) {
NSLog(#"matchArray %#", matchArray);
}
Addressing your comments, the reason why isEqualToString: does not show up in autocomplete is because Xcode cannot guess that matchArray contains NSStrings (it only knows it contains ids, that is, arbitrary Objective-C objects). If you really wanted to be sure, you can perform an explicit cast, but it doesn't matter if you don't:
if ([(NSString *)[matchArray objectAtIndex:0] isEqualToString:#"asdf"]) {
NSLog(#"matchArray %#", matchArray);
}

you want to use -objectAtIndex to get the array element. NOT the C array accessor syntax

try to use:
[[matchArray objectAtIndex:0] isEqualToString:#"asdf"];
anyway the string "asdf" should be #"asdf"

Related

NSLog pointer syntax

I'm a little bit confused about the syntax of NSLog. For example,
NSString *nameString = #"Name";
NSLog(#"nameString is: %#", nameString);
If my understanding is correct (which it very well may not be), then nameString is defined to be a pointer to a String. I thought then that this would print the memory address that nameString holds, not the value of that address. So, if that is true, then in the NSLog statement, to get the value of the pointer, shouldn't we need to use the asterisk notation to access what nameString points to like this:
NSLog(#"nameString is: %#", *nameString);
?
It has been a little while since programming in C, but since Objective-C is a superset of C I thought they would behave similarly.
An explanation would be greatly appreciated! Thanks!
The command %# is like "shortcut" that calls the method -description on the receiver. For an NSString it simply display the string itself, since is inherited from NSObject you can override it, very usefull if you create for own class. In that case the default behaviur is print the value of the pointer. If you want to print the address of the pointer in the string just replace with :
NSLog(#"nameString is: %p", nameString)
I think that you use an asterisk only to declare a pointer. Then, you only use the name you decided. For example:
NSString *foo = [[NSString alloc] initWithString:#"Hello"];
NSLog(#"%#", foo);
Correct me if I am wrong :)
It's an object and NSLog is a function that uses its format specifiers to determine what to do with the argument. In this case the specifier is %# which tells NSLog to call a method on an object.
Normally this will call the method "description" which returns an NSString but it probably does respondsToMethod first and falls through to some other string methods.

is there any way to get the return value from a method by using #selector except using double pointer?

I don't want to use double pointer. I am using a function in simpler form as below.
-(NSString *) getName
{
return name;
}
So what is the correct way to take the returned NSString *?
By using #selector(getName) i am not able to get the returned value name.
Thank you in advance
You should use NSInvocation object instance for calling a selector and resolving returned result.
performSelector: does give you the return value directly.
NSString * s = #"NEXT WE HAVE NUMBER FOUR, 'CRUNCHY FROG'.";
NSString * l = [s performSelector:#selector(lowercaseString)];
NSLog(#"%#", l); // prints "next we have number four, 'crunchy frog'."

Trouble comparing NSString to NSArray object

Ok, so I'm trying to check if an object from an NSArray equals something inputed by the User into a UITextField. It should work, but for some reason it dosn't. Here is my code:
if (theAnswer.text == [correctAnswers objectAtIndex:problemNumber]) {
NSLog(#"CORRECT");
}
else {
NSLog(#"wrong");
}
The console always give wrong.
I put this log in:
NSLog(#"%# %#", theAnswer.text, [correctAnswers objectAtIndex:problemNumber]);
And I get A A
wrong
printed everytime. Thanks for the help
Objective-C doesn't support the == operator for NSStrings. That will do a comparison of the pointers to the NSStrings and not the contents of the string itself.
Try
if([theAnswer.text isEqualToString:[correctAnswers objectAtIndex:problemNumber]]) {
}

NSString returning jibberish

Totally lost with this one. Here's my code:
theColor = [NSString stringWithFormat:#"white"];
NSLog(#"%s", theColor);
Which is returing:
†t†å
I must be doing something stupid, but can not figure it out for the life of me.
Change your print to:
NSLog(#"%#", theColor);
Hope it helps.
The thing is that %s expects a C-string (char array with a NULL terminator) and you are passing a NSString instance which is not the same as a C-string. The modifier you need in a format to print NSString content is %#.
%s is for printing C-style strings.
%# is for printing Objective-C objects (like NSString).
BTW: “theColor = [NSString stringWithFormat:#"white"];” – why not “theColor = #"white";”?
Greetings

RegExKitLite Expression Question

I'm having trouble coming up with an RegExKitLite expression that will match. I'm parsing a string and I want it to grab everything till it comes upon the first occurrence of a colon
What would be the expression in RegExKitLite to do that?
Thanks!
This regex will match everything from the start until (but excluding) the first colon:
^[^:]*
To include the first colon is as simple as putting it on the end:
^[^:]*:
So, to use either of those with RegexKitLite, you can do:
NSString * firstItem = [someString stringByMatching:#"^[^:]*" capture:0];
Note how there is no parentheses - since * is greedy you can simply use the negated class and use captured group 0 (i.e. the whole match).
It's worth noting that most languages will include functions that allow you to do this with a regular function, for example ListFirst(MyString,':') or MyString.split(':')[0]
I suspect Objective-C has something similar to this ... yep, see here
NSString *string = #"oop:ack:bork:greeble:ponies";
NSArray *chunks = [string componentsSeparatedByString: #":"];
To do this specifically with RegexKitLite, you'll need to do the following:
Add the RegexKitLite.h/.m files to your project
Import RegexKitLite.h into the file where you need to use regular expressions
Use the following to grab the stuff before the colon:
NSString * everythingBeforeTheColon = [someString stringByMatching:#"([^:]*):" capture:1];
I just updated my SO answer here, so I figured I'd use that to benchmark the standard foundation componentsSeparatedByString: and RegexKitLites componentsSeparatedByRegex:. The line of code inside the for() loop for each was (essentially):
NSString *string = #"oop:ack:bork:greeble:ponies";
for() { NSArray *chunks = [string componentsSeparatedByString: #":"]; }
for() { NSArray *chunks = [string componentsSeparatedByRegex: #":"]; }
Times returned were (time is in microseconds per operation):
componentsSeparatedByString: 3.96810us
componentsSeparatedByRegex: 2.46155us
EDIT:
I thought I'd go one better: How to use RegexKitLite to create a NSArray of NSArrays from a string containing multiple lines of colon separated data (ie, /etc/passwd). Modified from the comma separated value example in the RegexKitLite documentation. When finished, the variable splitLinesArray contains the finished product.
NSString *theString = #"a:b:c\n1:2:3\nX:Y:Z\n"; // An example string to work on.
NSArray *linesArray = [theString componentsSeparatedByRegex:#"(?:\r\n|[\n\v\f\r\\x85\\p{Zl}\\p{Zp}])"];
id splitLines[[linesArray count]];
NSUInteger splitLinesIndex = 0UL;
for(NSString *lineString in linesArray) { splitLines[splitLinesIndex++] = [lineString componentsSeparatedByRegex:#":"]; }
NSArray *splitLinesArray = [NSArray arrayWithObjects:splitLines count:splitLinesIndex];