views:

86

answers:

2
+1  Q: 

Weird cocoa bug?

Hey folks, beneath is a piece of code i used for a school assignment. Whenever I enter a word, with an O in it (which is a capital o), it fails! Whenever there is one or more capital O's in this program, it returns false and logs : sentence not a palindrome.

A palindrome, for the people that dont know what a palindrome is, is a word that is the same read left from right, and backwards. (e.g. lol, kayak, reviver etc) I found this bug when trying to check the 'oldest' palindrome ever found: SATOR AREPO TENET OPERA ROTAS.

When I change all the capital o's to lowercase o's, it works, and returns true. Let me state clearly, with this piece of code ALL sentences/words with capital O's return false. A single capital o is enough to fail this program.

-(BOOL)testForPalindrome:(NSString *)s position:(NSInteger)pos {
    NSString *string = s;
    NSInteger position = pos;
    NSInteger stringLength = [string length];
    NSString *charOne = [string substringFromIndex:position];
    charOne = [charOne substringToIndex:1];

    NSString *charTwo = [string substringFromIndex:(stringLength - 1 - position)];
    charTwo = [charTwo substringToIndex:1];
    if(position > (stringLength / 2)) {
        NSString *printableString = [NSString stringWithFormat:@"De following word or sentence is a palindrome: \n\n%@", string];
        NSLog(@"%@ is a palindrome.", string);
        [textField setStringValue:printableString];
        return YES;
    }
    if(charOne != charTwo) {
        NSLog(@"%@, %@", charOne, charTwo);
        NSLog(@"%i", position);
        NSLog(@"%@ is not a palindrome.", string);
        return NO;
    }
    return [self testForPalindrome:string position:position+1]; 
}

So, is this some weird bug in Cocoa? Or am I missing something?

  • B
+4  A: 

This of course is not a bug in Cocoa, as you probably knew deep down inside.

Your compare method is causing this 'bug in Cocoa', you're comparing the addresses of charOne and charTwo. Instead you should compare the contents of the string with the isEqualToString message.

Use:

if(![charOne isEqualToString:charTwo]) {

Instead of:

if(charOne != charTwo) {

Edit: tested it in a test project and can confirm this is the problem.

Yannick Compernol
Of course I knew this wansn't truly a bug in cocoa, I was just curious what the problem was. I mean, why is this only happening on the capita l O and not on the other letters? The code seemed allright, at first glance. I knew Java for example has a .Equals method, which i count directly find in Cocoa. But now it's here ill test it right away!
BryCry
2010-09-27 17:37:44.898 ADS Practicum 2[447:a0f] Checking for Palindrome2010-09-27 17:37:44.899 ADS Practicum 2[447:a0f] SATOR AREPO TENET OPERA ROTAS is a palindrome. Looks like it worked :) Thanks people!
BryCry
When I ran your code in a test project, I couldn't get "aza" to validate for instance. And it has no capital O.
Yannick Compernol
Note that `isEqualToString:` is case-sensitive, so it will only work for palindromes that use the same case throughout. For mixed-case (e.g., sentence-case) input, you'll want a case-insensitive comparison, as shown by Stephen Furlani in his answer.
Peter Hosey
+3  A: 

Don't use charOne != charTwo

Instead use one of the NSString Compare Methods.

if ([charOne caseInsensitiveCompare:charTwo] != NSOrderedSame)

It may also have to do with localization (but I doubt it).

Stephen Furlani