简体   繁体   中英

Palindrome comparing punctuation only at the end, using pointers

This is a palindrome checker I have made in c. It works for all inputs, whether they have punctuation or not EXCEPT when the last item is a punctuation. In this case it does not skip it and compares and then says that it is not a palindrome when in fact it is. EX(lived, devil. will not be a palindrome but lived, devil will be).

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <ctype.h>

#define max 180

bool is_palindrome(const char *message);

int main()
{
    char message[max+1];

    printf("Enter a message: ");
    gets(message);
    if(!*message)
     {
         printf("input error");
         return 0;
     }

     if (is_palindrome(message)) printf("Palindrome\n");
     else printf("Not a palindrome");

     return 0;
 }

 bool is_palindrome(const char *message)
 {
     char *p, *p2;
     bool palindrome = true;

     p = message;
     p2 = message;

     for(;;)
     {
         while(*p)p++;

         while(*p2)
         {
             while(!isalpha(*p)) p--;
             while(!isalpha(*p2)) p2++;

             if (toupper(*p) != toupper(*p2))
             {
              palindrome = false;
              break;
             }else
             {
                 p--;
                 p2++;
             }

         }
         break;
     }
     return palindrome;
 }

The main problem with you code is in the following lines -

while(!isalpha(*p)) p--;
while(!isalpha(*p2)) p2++;

This skips over all the non-alphabetical characters. Which is fine and as expected. But the problem is that, it also skips over \\0 which is the string terminator.

What happens is that as p2 goes ahead, it reaches the end of the string, it starts matching the . at the end. It skips that, but also skips the \\0 . This causes it to read beyond the string (which might be undefined behavior, if the buffer ends there) and it produces wrong result.

What you need to do is, also stop if p2 reaches the end.

So change the lines to -

while(!isalpha(*p)) p--;
while(*p2 != '\0' && !isalpha(*p2)) p2++;
if (*p2 == '\0')
    break;

These modifications will make your code stop at the right point and will solve your error. Also the for(;;) and the unconditional break at the end are redundant. So can be removed.

DEMO on Ideone.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM