سؤال

I have an assignment I am working on where I must take a sentence input from a user, print the words in reverse order, check for anagrams, and check for palindromes. I got a function working for anagrams, and I almost have my palindrome function working. For now, I am only asking for two words so I can get my functions working. However, for some reason, whenever I input a lengthy palindrome (ex; racecar or detartrated compared to Mom or Dad) for both words that I ask for, the palindrome function gets messed up.

Here is the code;

#include <stdio.h>
#include <ctype.h> //Included ctype for tolower / toupper functions
#define bool int
#define true 1
#define false 0

//Write boolean function that will check if a word is a palindrome
bool palindrome(char a[])
{
    int c=0;
    char d[80];
    //Convert array into all lower case letters
    while (a[c])
    {
        a[c] = (tolower(a[c]));
        c++;
    }
    c = 0;

    //Read array from end to beginning, store it into another array
    while (a[c])
        c++;

    while(a[c] != 0 && c > -1)
    {
        d[c] = a[c];
        c--;
    }

    c = 0;

    while(a[c])
    {
        printf("%c", d[c]);
        printf("%c", a[c]);
        c++;
    }
    //If two arrays are equal, then they are palindromes
    for(c = 0; a[c] && d[c]; c++)
    {
        while(a[c] && d[c])
        {
        if(a[c] != d[c])
            return false;
        }
    }
    return true;
}

int main(void)
{
    char a[80], b[80];
    bool flagp;
    //Prompt user to enter sentence
    printf("Enter a word: ");
    gets(a);

    flagp = palindrome(a);

    if (flagp)
    {
        printf("\nThe word is a palindrome.");
    }
    else
    {
        printf("\nThe word is not a palindrome.");
    }

    return 0;
}

It outputs this;

Enter first word: racecar
_r▬a↨c e c a r
The word is not a palindrome.

However, if I enter 'racecar', it incorrectly states it's not a palindrome.

Please tell me what I am doing wrong :'(

هل كانت مفيدة؟

المحلول

  1. So a[c] != d[c] is true when you expect it to be false.
  2. You've demonstrated with your printf that this is because d[c] is garbage.
  3. That means that d doesn't contain the reverse of a.
  4. So this leads one to inspect the following snippet:

    while(a[c] != 0 && c > -1)
    {
        d[c] = a[c];
        c--;
    }
    

    It's attempting to create a reversed copy, but it's quite clearly failing at reversing anything seeing as it's putting at the same index as it's taking.

(You did the first three steps. Why did you stop there?)

Honestly, there's no reason for d to exists at all. It can all be done in-place.

   +---+---+---+---+---+---+---+
a: | r | a | c | e | c | a | r |
   +---+---+---+---+---+---+---+
     ^                       ^
     |   compare these two   |


         ^               ^
         |  then these   |


                ...

So the code would look like:

size_t len = strlen(a);
if (len) {
   size_t i = 0;
   size_t j = len - 1;
   while (i < j) {
      if (a[i++] != a[j--])
         return 0;
   }
}

return 1;

Notes:

  1. Please don't do #define true 1 and #define false 0. These differ from C's definition, so you could get the wrong result if you do if (b == true) instead of if (b).

  2. c usually denotes a char. i (and j and k) are more commonly used for indexes.

نصائح أخرى

The problem is in your palindrome function. In the snippet

while(a[c] != 0 && c > -1)
{
    d[c] = a[c];
    c--;
}

you are not reversing a.

And snippet

while (a[c])
    c++;  

cause c to go out of bound by 1.

I fixed these issues. Your modified code:

bool palindrome(char a[])
{
    int c=0;
    char d[80];
    //Convert array into all lower case letters
    while (a[c])
    {
        a[c] = (tolower(a[c]));
        c++;
    }
    c = 0;

    //Read array from end to beginning, store it into another array
    while (a[c])
        c++; 
        c=c-1; // Number of elements in a is one less than that of counter c.

    int i = 0;  // taking another counter for array d
    while(a[c] != 0 && c > -1)
    {
        d[i] = a[c];
        i++;
        c--;
    }
    d[i] = '\n'; // last element of array mut be a nul char
    c = 0;

    while(a[c])
    {
        printf(" %c\t", d[c]);
        printf(" %c\n", a[c]);
        c++;
    }
    //If two arrays are equal, then they are palindromes
    for(c = 0; a[c] && d[c]; c++)
    {

         if(a[c]  != d[c] )
            return false;

    }
    return true;
}  

After all, this function is not good enough for checking palindrome. Example:

Input:

I am a     I

you will get

The word is not a palindrome.  
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top