I'm writing code which checks if an array is palindrome or not:
Write a program that reads a message, then checks whether it's a palindrome
(the letters in the message are the same from left to right as from right to left):Enter a message: He lived as a devil, eh?
PalindromeEnter a message: Madam, I am Adam.
Not a palindrome
When I have entered He lived as a devil, eh?
,
it gives me the output Not a palindrome
,
but the real output should be palindrome
.
Below code is what I have tried so far.
#include <stdio.h>
#include <ctype.h>
#define MAX_LEN 100
int main(void) {
char message[MAX_LEN];
char c, *p = message, *q;
printf("Enter a message: ");
while ((c = toupper(getchar())) != '\n' & p < message + MAX_LEN) {
if (isalpha(c))
*p++ = c;
}
p--;
for (q = message; q < p; q++, p--) {
if (*p != *q) {
printf("Not a palindrome\n");
return 0;
}
}
printf("Palindrome\n");
return 0;
}
For starters you should declare the variable c
as having the type int
. The user can interrupt the input process in which case the function getchar
returns integer value EOF
and you should check whether this occurred.
char *p = message, *q;
int c;
There is a bug in the condition of the while statement
while ((c = toupper(getchar())) != '\n' & p < message + MAX_LEN) {
Instead of the bitwise operator &
you have to use the logical AND operator &&
.
As I already have said you should check in the condition of the while statement whether the user interrupted the input. For example
while ( p < message + MAX_LEN && ( c = toupper(getchar())) != EOF && c != '\n') {
if (isalpha(c))
*p++ = c;
}
The argument of a call of toupper
or isalpha
should be converted to the type unsigned char. Otherwise in general without the casting such a call can invoke undefined behavior.
It is desirable not to exclude from an entered string numbers. SO it is better at least to call the function isalnum
instead of the function isalpha
.
The user can enter an empty string in this case this decrement of the pointer
p--;
also can invoke undefined behavior.
And it is better when a program has one point to exit.
The program can look the following way
#include <stdio.h>
#include <ctype.h>
#define MAX_LEN 100
int main(void)
{
char message[MAX_LEN];
printf( "Enter a message: " );
char *p = message;
for ( int c; p < message + MAX_LEN && ( c = getchar() ) != EOF && c != '\n'; )
{
if( isalnum( ( unsigned char )c ) )
{
*p++ = toupper( ( unsigned char )c );
}
}
int palindrome = 1;
if ( p != message )
{
for ( char *q = message; palindrome && q < --p; ++q )
{
palindrome = *q == *p;
}
}
printf( "The entered message is %spalindrome\n",
palindrome ? "" : "not " );
return 0;
}
Its output might look for example like
Enter a message: He lived as a devil, eh?
The entered message is palindrome
or like
Enter a message: Madam, I am Adam
The entered message is not palindrome
Pay attention to that instead of using a loop with numerous calls of the function getchar
you could use only one call of the function fgets
fgets( message, sizeof( message ), stdin );
or
if ( fgets( message, sizeof( message ), stdin ) != NULL )
{
// check whether the entered string is a palindrome
}