2017-11-09 7 views
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; 
} 
+0

'gets'は使用しないでください。私たちにそれをしないでください。それは危険な関数なので、C標準から削除されています。可能であれば、['fgets'](http://en.cppreference.com/w/c/io/fgets)を使用してください。 –

+0

私は、K.N.による、近代的アプローチの教科書をCプログラミングから学んできました。キングだからこそ、私はフルラインを読むのに使われるようにその機能を選んだのです。しかし、それは将来の参考のために知って良いです、ありがとう。 – OliviaA

+1

[取得機能が危険なので、使用しないのはなぜですか?](https://stackoverflow.com/q/1694036/995714) –

答えて

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; 

-

そうに行を変更します。 また、for(;;)と最後の無条件ブレークは冗長です。だから削除することができます。

DEMOがIdeoneにあります。

関連する問題