Why is my strcmp always returning true? - iphone

I'm trying to compare user text input from an iphone app with the text in a static array I have declared. It is always returning "true", even when the text is different. After doing the strncmp, I display both text fields. To the human eye, they are what I expect the fields to be. The debugmsg I return to the screen shows what I expect the values to be, but the compare is always coming up true. Any suggestions would be appreciated. Thanks.
if (strncmp(SymbolEntered.text,
[NSString stringWithCString:elements_table2[idx].element_symbol],2)==0)
{
DebugMsg.text = [NSString stringWithCString:"Correct answer"];
}
else
{
DebugMsg.text = [NSString stringWithCString:"Incorrect!"];
}
DebugMsg2.text = SymbolEntered.text;
DebugMsg3.text = [NSString stringWithCString:elements_table2[idx].element_symbol];

You really should do this with NSString, which has tons of comparison methods implemented, instead of CString (why are you using CString?). strcmp doesn't work with NSString.
if([SymbolEntered.text isEqualToString:[NSString stringWithCString:elements_table2[idx].element_symbol]]) {
DebugMsg.text = #"Correct answer";
} else {
DebugMsg.text = #"Incorrect answer";
}
Also instead of:
DebugMsg.text = [NSString stringWithCString:"Correct answer"];
you can do this:
DebugMsg.text = #"Correct answer";

Related

iOS rangeOfString can't locate the string that is definitely there

I am writing code in objective-c. I would like to extract a url from a string.
Here is my code:
NSMutableString *oneContent = [[latestPosts objectAtIndex:i] objectForKey:#"content"];
NSLog(#"%#", oneContent);//no problem
NSString *string = #"http";
if ([oneContent rangeOfString:string].location == NSNotFound) {
NSLog(#"string does not contain substring");
} else {
NSLog(#"string contains substring!");
}
As you can see, I want to extract a url from the oneContent string, and I have checked that oneContent definitely contains "http", but why does the result show nothing?
Is there some better way to extract the url?
Check oneContent or the actual code you are running.
This works:
NSMutableString *oneContent = [#"asdhttpqwe" mutableCopy];
NSLog(#"%#", oneContent);//no problem
NSString *string = #"http";
if ([oneContent rangeOfString:string].location == NSNotFound) {
NSLog(#"string does not contain substring");
} else {
NSLog(#"string contains substring!");
}
NSLog output:
Untitled[5911:707] asdhttpqwe
Untitled[5911:707] string contains substring!
It is probably best not to use a Mutable string unless there is some substantial reason to do so.
I would suggest using NSScanner.

UITextView Autocomplete modification

I'm currently using this HTAutocompleteTextField to fill in a UITextField with a predefined list, should A user start typing in an entry that already exists. There are a couple of problems that I've been having however. The first is that it seems to stop when a comma is typed in (but not apostrophes). I've been looking around and I'm really not sure why it's doing it. I thought at one point it could be that the comma was a different comma, like an apostrophe issue I had due to importing the list from a word document. However, it wasn't the case. The second issue is more of an addition which I'm not really sure how to implement. I also want the autosuggest to detect suggestions for words in mid string, not just from the beginning. So for instance typing in "String" would suggest "This is a String". This currently how it does the auto suggest, but I have no idea how to do the above things.
NSString *prefixLastComponent = [componentsString.lastObject stringByTrimmingCharactersInSet:space];
if (ignoreCase)
{
stringToLookFor = [prefixLastComponent lowercaseString];
}
else
{
stringToLookFor = prefixLastComponent;
}
for (NSString *stringFromReference in colorAutocompleteArray)
{
NSString *stringToCompare;
if (ignoreCase)
{
stringToCompare = [stringFromReference lowercaseString];
}
else
{
stringToCompare = stringFromReference;
}
if ([stringToCompare hasPrefix:stringToLookFor])
{
return [stringFromReference stringByReplacingCharactersInRange:[stringToCompare rangeOfString:stringToLookFor] withString:#""];
}
}
If anyone could give me any pointers on how to get this done, I'd appreciate it.
Regards,
Mike
Managed to go about solving both issues. For any one who uses this Git Repository, the reason why commas don't work when using the preset methods is because of NSArray *componentsString = [prefix componentsSeparatedByString:#","];. Remove the comma so it's NSArray *componentsString = [prefix componentsSeparatedByString:#""]; and it should work nicely. To fix the other problem where it only detects the start of words, I changed the methods a little. Here are my changes in HTAutocompleteManager.m
int i = 0;
for (NSString *stringFromReference in colorAutocompleteArray)
{
NSString *stringToCompare;
if (ignoreCase)
{
stringToCompare = [stringFromReference lowercaseString];
}
else
{
stringToCompare = stringFromReference;
}
if ([stringToCompare hasPrefix:stringToLookFor])
{
//NSLog(#"Removing String: %# atIndex: %d", [colorAutocompleteArray objectAtIndex:i], i);
[colorAutocompleteArray removeObjectAtIndex:i];
[colorAutocompleteArray insertObject:stringFromReference atIndex:0];
//NSLog(#"Adding String atIndex 0: %#", stringFromReference);
return [stringFromReference stringByReplacingCharactersInRange:[stringToCompare rangeOfString:stringToLookFor] withString:#""];
}
else if ([stringToCompare hasSuffix:stringToLookFor] && ([stringToLookFor length] >= 3)) {
return [NSString stringWithFormat:#" %#", stringFromReference];
}
else if (!([stringToCompare rangeOfString:stringToLookFor].location == NSNotFound) && ([stringToLookFor length] >= 3))
{
return [NSString stringWithFormat:#" %#", stringFromReference];
}
++i;
}
The reason for reordering the Array is because after the 3rd character is typed it will prioritise the other two if statements because they will be reached first if there is a generic term in multiple entries in the array (like "Street" in a list of locations). I know it's not necessary to have the "hasSuffix" if statement, but I left it in case someone wants to use it on it's own. Lastly, I added in a space before stringFromReference so that it doesn't look weird when there's a suggestion straight after the input text. When we exit the UITextField we remove this space like this (inside HTAutocompleteTextField.m - commitAutocompleteText):
NSString *currentText = self.text;
if ([self.autocompleteString isEqualToString:#""] == NO
&& self.autocompleteDisabled == NO)
{
if ([self.autocompleteString hasPrefix:#" "]) {
self.autocompleteString = [self.autocompleteString substringFromIndex:1];
}
self.text = [NSString stringWithFormat:#"%#", self.autocompleteString];
self.autocompleteString = #"";
[self updateAutocompleteLabel];
}
return ![currentText isEqualToString:self.text];
Hope this makes sense to anyone who's in a similar situation.
Mike

If statement does not work properly

This is my code:
NSString * atime = [NSString stringWithFormat:#"%#",[theDataObject.minuteArray objectAtIndex:indexPath.row]];
NSLog(#"value of atime is:%#",atime);
if (atime==#"0") {
NSString * timeStr = [NSString stringWithFormat:#"%#s",[theDataObject.secondArray objectAtIndex:indexPath.row]];
cell.timeLabel.text = timeStr;
}
else {
NSString * timeStr = [NSString stringWithFormat:#"%#m%#s",[theDataObject.minuteArray objectAtIndex:indexPath.row],[theDataObject.secondArray objectAtIndex:indexPath.row]];
cell.timeLabel.text = timeStr;
}
But it never return first statement only return second statement,even is atim value is 0.
log value:
MyAudioRecorder[2484:10703] value of atime is:0
also tried to put 0 instead of #"0",still does not work.
if (atime==#"0")
Compares the memory address of atime with the address of constant string #"0".
if ([atime isEqualToString:#"0"])
Compares the values that are stored in the two memory locations.
From your requirement it is seen that you want to compare the value not the memory location. So go for 2nd one.
Try the following:
if ([atime isEqualToString : #" "]) {}
isEqualToString: ->
- (BOOL)isEqualToString:(NSString *)aString
Returns a Boolean value that indicates whether a given string is equal to the receiver using a literal Unicode-based comparison.
Discussion -> When this method compares two strings, if the individual Unicodes are the same, then the strings are equal
For more you can access apple NSString Class Reference
if([atime isEqualToString:#"0"])
{
}
else
{
}

Why isn't this conditional statement working with NSUserDefault?

I'm having a problem getting one of my conditional statements to display data correctly. Here is the code I'm working with:
NSUserDefaults *pickerDefaults = [NSUserDefaults standardUserDefaults];
NSString *myString = [pickerDefaults stringForKey:#"userpicker"];
NSString *string = #"Name1";
NSLog(#"%#",myString); //This prints out Name1
NSLog(#"%#",string); //This also prints out Name1
if (myString == string) {
[pickerArray addObject:#"Name Other"];
}
else {
return;
}
I can't get this if statement to add that object to the UIPicker eventhough both strings are equal to each other. However, if I change it to not equal to != then it display's the object in the UIPickerView. I don't understand what I'm doing wrong. Any help would be great. Thanks.
To compare string objects, don't use their pointer values, but compare using
[string isEqualToString:myString]
if (myString == string) // Wrong : It compares address of two NSStrings
if ([myString isEqualToString:string]) // This compares values of NSStrings
{
}

Can't get rid of this warning?

I'm getting this warning "Format not a string literal and no format arguments? Any ideas?
-(BOOL)isFirstPointReached{
NSString *firstPoint = [NSString stringWithFormat:[pointsToFillArray objectAtIndex:0]];
NSString *lastPoint = [NSString stringWithFormat:[pointsToFillArray lastObject]];
if([firstPoint isEqualToString:lastPoint]){
return YES;
}
else{
return NO;
}
}
A few points...
The pointsToFillArray is an array of objects and the compiler does not know if it contains NSStrings or any other type of object. To get rid of the error you would cast it to (NSString*)
Secondly, the stringWithFormat is normally used to create a string from a few different pieces of data and does not need to be used in this case
Thirdly, you could just create pointers to the objects within the array and then do your check
The following should work for you:
NSString *firstPoint = (NSString*)[pointsToFillArray objectAtIndex:0];
NSString *lastPoint = (NSString*)[pointsToFillArray lastObject];
if ([firstPoint isEqualToString:lastPoint]) {
return YES;
}