0

这是我在 c 中制作的回文检查器。它适用于所有输入,无论它们是否有标点符号,除非最后一项是标点符号。在这种情况下,它不会跳过它并进行比较,然后说它不是回文,而实际上它是。EX(活过,魔鬼。不会是回文,而是活过,魔鬼会)。

#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;
 }
4

1 回答 1

0

您的代码的主要问题在于以下几行 -

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

这会跳过所有非字母字符。这很好,正如预期的那样。但问题是,它也跳过了\0哪个是字符串终止符。

发生的事情是,随着p2前进,它到达字符串的末尾,它开始匹配.末尾的。它跳过了那个,但也跳过了\0. 这会导致它读取字符串之外的内容(如果缓冲区在那里结束,这可能是未定义的行为)并产生错误的结果。

你需要做的是,如果p2到达终点也停止。

所以将这些行更改为 -

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

这些修改将使您的代码停在正确的位置并解决您的错误。最后的 thefor(;;)和无条件中断也是多余的。所以可以去掉。

在Ideone上演示。

于 2017-11-09T05:09:37.460 回答