1

I wrote two sample programs to check for a palindrome string. But in both I am getting output like, its not a palindrome number. What I am missing?

I strictly assume somehow code is executing my if statement and put flag in to 1. May be because of that length calculation. Anyone has a better idea?

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    #include <conio.h>
    
    int main(void) {
        setbuf(stdout,NULL);
        char name[100];
        int i,length,flag=0,k;
        printf("Enter your name");
        /*scanf("%s",name);*/
        gets(name);
        length=strlen(name);
        for(i=0;i<=length-1;i++)
        {
            for(k=length-1;k>=0;k--)
            {
                if(name[i]!=name[k])
                {
                    flag=1;
                    break;
    
                }
    
                }
            }
    
        if(flag==0)
        {
            printf("Give word is a palindrome");
        }
        if(flag==1)
        {
            printf("This is NOT a palindrome word");
        }
        return 0;
        }

and

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>

int main(void) {
    setbuf(stdout,NULL);
    char name[100];
    int i,length,flag=0;
    printf("Enter your name");
    /*scanf("%s",name);*/
    gets(name);
    length=strlen(name);
    for(i=0;i<=length/2;i++)
    {
        if(name[i]!=name[length-1])
        {
            flag=1;
        }
    }


    if(flag==0)
    {
        printf("Give word is a palindrome");
    }
    if(flag==1)
    {
        printf("This is NOT a palindrome word");
    }
    return 0;
    }
Amal K
  • 4,359
  • 2
  • 22
  • 44
SOORAJ SR
  • 17
  • 7
  • 3
    In the second snippet, the statement `if (name[i] != name[length - 1])`, I suppose you want `if (name[i] != name[length - i - 1])` – Ruks Jul 04 '21 at 07:51
  • 1
    In the 1st code you're comparing every letter with every letter; in the second code you're comparing always with the last letter – pmg Jul 04 '21 at 07:52
  • Read [this](https://stackoverflow.com/questions/25385173/what-is-a-debugger-and-how-can-it-help-me-diagnose-problems). – n. m. could be an AI Jul 04 '21 at 08:00
  • 1
    OT: `for(i=0;i<=length-1;i++)` --> `for(i=0;i – Support Ukraine Jul 04 '21 at 08:03
  • Did you by chance search `"[c] palindrome"` in the search box? There are dozens, if not hundreds of answers. Perhaps [Answer - How to remove spaces and check if a string is a palindrome?](https://stackoverflow.com/a/55414017/3422102) – David C. Rankin Jul 04 '21 at 08:34
  • Strongly suggest you forget `gets()` exists (strictly since C11 standard library it does not). – Clifford Jul 04 '21 at 08:58
  • _"like,its not a palindrome number"_ : A palindromic number is quite a different thing than a palindromic string. Did you mean "_number_"? – Clifford Jul 04 '21 at 09:13

3 Answers3

2

First Algorithm

The algorithm you are using in the first program involves comparing each letter to every other letter which does not help in determining if the number is a palindrome and it does not seem fixable.

Second Algorithm

The problem with the second approach, however, is you are always comparing name[i] to name[length]. Instead change it to length-i-1. This will start comparing from length-1 and decrement the length of the character by 1 for every next iteration:

for(i = 0;i <= length / 2;i++)
{
    if(name[i] != name[length-i-1])
    {
        flag=1;
        break;
    }
}

gets() and buffer overflow

Do not use gets. This method is susceptible to a buffer overflow. If you enter a string longer than 100 characters, it will result in undefined behavior. Use fgets instead for deterministic behavior:

fgets(name, sizeof(name), stdin);

This takes in the size of the buffer and only reads up to sizeof(name) characters.

Full code

Ideally, you should consider wrapping the logic to check if the string is a palindrome in a function:

int is_palindrome(char*);

int main(void) 
{
    char name[100];
    setbuf(stdout,NULL);
    printf("Enter your name");
    fgets(name, sizeof(name), stdin);
    
    if(is_palindrome(name))
    {
        printf("The given word is a palindrome");
    }
    else
    {
        printf("This is NOT a palindrome word");
    }
    return 0;
    
}

int is_palindrome(char* name)
{
    int length = strlen(name);
    int flag = 0, i;
    for(i = 0;i <= length / 2; i++)
    {
        if(name[i]!=name[length-i-1])
        {
            return 0;
        }
    }
    return 1;
}
Amal K
  • 4,359
  • 2
  • 22
  • 44
  • 1
    You need test for an remove the `'\n'` line-end that `fgets()` includes. Otherwise no input is palindromic. Since the input method is not really part of the question (even though the OP code is clearly dangerous), it would be simpler to avoid it and show tests with string constants. Also suggest `int is_palindrome( const char* name )`. – Clifford Jul 04 '21 at 09:03
0

Try this

    #include <stdio.h>
    #include <stdlib.h>

    #include <string.h>
    int main() {
       char text[100];
       int begin, middle, end, length = 0;
       printf("enter the name: ");
       scanf("%s",text);
       while ( text[length] != '\0' ){
            length++;}

       end = length - 1;
       middle = length/2;
       for ( begin = 0 ; begin < middle ; begin++ ) {
           if ( text[begin] != text[end] ) {
              printf("Not a palindrome.\n");
              break;
           }
           end--;
         }
         if( begin == middle )
              printf("Palindrome.\n");
              return 0;
     }

The problem with the first piece of code is you are comparing it more than required, compare it with length-i-1.

The main problem with the second code is you are comparing it with only the last letter of a word.

Hope you understood your mistake

Clifford
  • 88,407
  • 13
  • 85
  • 165
Hemesh
  • 107
  • 9
  • Just a reminder `scanf("%s",text);` is no safer than `gets()`, see [Why gets() is so dangerous it should never be used!](https://stackoverflow.com/q/1694036/3422102). Always, *always* use a field width modifier to explicitly prevent reading beyond the end of your array and invoking *Undefined Behavior* (and preventing a buffer-exploit). E.g. `if (scanf("%99s",text) != 1) return 1;` Also, what happens in your code if the user enters `"I"` alone? (hint: `begin = middle = 0;` and `end = 1`) – David C. Rankin Jul 04 '21 at 08:27
  • yep, thank you for your info but as this is a simple program I didn't consider much about safety/security, next time I will I keep that in mind while implementing. – Hemesh Jul 04 '21 at 08:32
  • Sure, no ding, just happy to help point out an "opportunity for improvement" `:)` – David C. Rankin Jul 04 '21 at 08:33
  • Is there any other mistakes with my solution – Hemesh Jul 04 '21 at 08:36
  • Your indentation on `if( begin == middle )` is a bit misleading as it is unguarded by `{ .. }` and `return 0;` isn't part of the `if` (that should be clear). Other than that it seems to function nicely. Other thought would be to use `fgets (text, sizeof text, stdin)` and then use `text[strcspn (text, "\n")] = 0;` to remove the `'\n'` from the end. That way you can handle `"A man a plan a canal Panama"` You have included `string.h` so change `while ( text[length] != '\0' )` to `length = strlen (text);` – David C. Rankin Jul 04 '21 at 08:40
  • If you do use `fgets()` so that you can handle input with whitespace, you will need to adjust your algorithm to ignore whitespace. – David C. Rankin Jul 04 '21 at 08:47
  • Sure thank you mate, I will do it properly next time and I am new to stack overflow, so I am learning things, next I will rectify it – Hemesh Jul 04 '21 at 08:49
  • Since the question is about the algorithm, not the user input method you could avoid criticism by only providing the code for the algorithm (as a fragment or a standalone function). The input method criticism applied to the OP code too; you can either avoid the issue or address it, but best not to duplicate it perhaps. Since it is not really the question being asked, I'd go for avoidance. See my answer to see how I avoided the issue. – Clifford Jul 04 '21 at 08:50
  • @Clifford technically, the question should likely have been marked a dupe given the 100+ palindrome QA already present. – David C. Rankin Jul 04 '21 at 09:06
  • @DavidC.Rankin Except the question is "what did I do wrong?" not "tell me the algorithm" so it is unlikely that there is a duplicate. But agreed the OP could have searched for a solution. – Clifford Jul 04 '21 at 09:11
0

There is plenty wrong with both your attempts. I strongly suggest using a debugger to investigate how your code works (or doesn't).

Your first attempt performs length2 (incorrect) comparisons, when clearly only length / 2 comparisons are required. The second performs length / 2 comparisons but the comparison is incorrect:

name[i] != name[length-1] ;

should be:

name[i] != name[length - i - 1] ;

Finally you iterate exhaustively when you could terminate the comparison as soon as you know they are not palindromic (on first mismatch).

There may be other errors - to be honest I did not look further than the obvious, because there is a better solution.

Suggest:


#include <stdbool.h>
#include <string.h>

bool isPalindrome( const char* str )
{
    bool is_palindrome = true ;
    size_t rev = strlen( str ) - 1 ;
    size_t fwd = 0 ;
    
    while( is_palindrome && fwd < rev )
    {
        is_palindrome = (str[fwd] == str[rev]) ;
        fwd++ ;
        rev-- ;
    }

    return is_palindrome ;
}

In use:

int main()
{
    const char* test[] = { "xyyx", "xyayx", "xyxy", "xyaxy" } ;
    for( size_t t = 0; t < sizeof(test)/sizeof(*test); t++ )
    {
        printf("%s : %s palindrome\n", test[t], 
                                       isPalindrome( test[t] ) ? "Is" : "Is not" ) ;
    }
    
    return 0;
}

Output:

xyyx : Is palindrome
xyayx : Is palindrome
xyxy : Is not palindrome
xyaxy : Is not palindrome
Clifford
  • 88,407
  • 13
  • 85
  • 165
  • 1
    @SOORAJSR You are welcome, but do note: https://meta.stackexchange.com/questions/126180/is-it-acceptable-to-write-a-thank-you-in-a-comment (upvotes/accepts preferred). – Clifford Jul 04 '21 at 14:38
  • I am totally a noob coder,still learning things.Your answer helped me to find the mistake i made. – SOORAJ SR Jul 04 '21 at 14:41