I'm supposed to make a code that determines if entered string is a palindrome, the code is supposed to have 3 functions. The first is to determine if string is palindrome, the second is to use isalpha()
to remove all non letters and the third is to use tolower()
to remove the difference between upper and lower case letters. I made all 3 separate functions but now that I have to combine them. The code just gives exception thrown.
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int isPalindrome(char inputString[])
{
int middle = strlen(inputString) / 2;
int len = strlen(inputString);
for (int i = 0; i < middle; i )
if (inputString[i] != inputString[len - i - 1])
{
return 0;
}
else
{
return 1;
}
}
void checker(char stringWithoutSpace[], char bigArray[])
{
int j = 0;
for (int i = 0; i < strlen(stringWithoutSpace); i )
{
if (isalpha(stringWithoutSpace[i]) != 0)
{
bigArray[j ] = stringWithoutSpace[i];
}
}
}
void lowerCase(char* string)
{
int i;
for (i = 0; string[i]; i )
{
string[i] = tolower(string[i]);
}
}
#define SIZE 1000
int main(void) {
int repeat = 1;
char arrayPalindrome[SIZE];
char bigArray[SIZE];
while (repeat == 1)
{
printf("Enter a sentence: ");
scanf_s("%s", &arrayPalindrome);
checker(arrayPalindrome, bigArray);
lowerCase(arrayPalindrome, bigArray);
if (isPalindrome(arrayPalindrome) == 1)
{
printf("This is a palindrome.");
}
else
{
printf("this in not a palindrome: ");
}
printf("Do you want to enter another sentence (0 for no, 1 for yes)?");
scanf_s("%d", &repeat);
}
return 0;
}
CodePudding user response:
For starters this call of scanf_s
is incorrect.
scanf_s("%s", &arrayPalindrome);
You have to write
scanf_s("%s", arrayPalindrome, rsize_t( sizeof( arrayPalindrome ) ) );
The function checker
does not build a string in the array bigArray
because you forgot to append the stored sequence of characters in the array with the terminating zero character '\0'
.
Moreover the function does not make sense because the array bigArray
is not used anymore in the program.
The function lowerCase
is declared with one parameter
void lowerCase(char* string);
but is called with two arguments.
lowerCase(arrayPalindrome, bigArray);
Pay attention to that there is no need to declare the auxiliary array bigArry
.
And the program should not change the original string.
The program can look for example the following way
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int lowerCase( char c )
{
return tolower( c );
}
int checker( char c )
{
return isalpha( ( unsigned char )c ) != 0;
}
int isPalindrome( const char s[] )
{
int is_palindrome = 1;
for (const char *first = s, *last = s strlen( s ); is_palindrome && first < last; first)
{
while (first < last && !checker( *first )) first;
if (first != last)
{
while (--last != first && !checker( *last ));
}
is_palindrome = first == last || lowerCase( *first ) == lowerCase( *last );
}
return is_palindrome;
}
int main( void )
{
const char *s = "12A b B a345";
printf( "\"%s\" is %spalindrome\n", s, isPalindrome( s ) ? "" : "not " );
}
The program output is
"12A b B a345" is palindrome
CodePudding user response:
Others, in comments and answers, have addressed the shortcomings in the code you presented. This answer addresses the heuristic approach to the problem.
As you are experiencing, every line of code is an opportunity for a bug to occur.
Acknowledging that the problem statement may have specified "write three functions", there is no need for so many. A single function does all that is necessary:
#include <stdio.h> // all that is needed
bool isPalindrome( const char s[] ) {
// a "custom" 7bit ASCII "look up" table with exclusion ('.') and 'tolower()' equivalence
char *tbl =
"................................................0123456789......"
".abcdefghijklmnopqrstuvwxyz......abcdefghijklmnopqrstuvwxyz.....";
// 'L'eft and 'R'ight indexing into the passed string
size_t L = 0, R = 0;
// find the end of the string (its 'r'ight index)
while( s[R] ) R ; // poor boy's 'strlen(s)'. '\0' does not matter.
do {
// adjust indexes L & R rejecting characters
// seek to "meet in the middle" of a palindromic string
while( L <= R && tbl[ s[L] ] == '.' ) L ;
while( L <= R && tbl[ s[R] ] == '.' ) R--;
} while( L <= R && tbl[ s[L] ] == tbl[ s[R] ] && (L =1) > 0 && (R-=1) > 0 );
// string is palindromic if it has passed the tests above
return L >= R;
}
int main() {
// without the drudgery of re-entering test strings,
// this "test harness" examines 3 different strings
// giving the evaluation of each. Easy to add more test cases.
char *strs[] = {
"LeVrEl",
"level",
"123Madam I'm Adam321",
};
for( int i = 0; i < sizeof strs/sizeof strs[0]; i )
printf( "%s - '%s'\n", isPalindrome( strs[i] ) ? "Yes" : "No ", strs[i] );
return 0;
}
No - 'LeVrEl'
Yes - 'level'
Yes - '123Madam I'm Adam321'
Far fewer lines of code, and should be "easy to follow" when one envisions a string as simply a contiguous array of characters.
If the assignment is to write 3 functions, one could add two more "no-op" functions to fulfill that criteria:
int thing1(void) { return 1; }
int thing2(void) { return 2; }
EDIT: With the (very good) advice to utilise standard library functions, here is much the same thing again (still considering digits to be 'testable' characters.)
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int isPalindrome( const char s[] ) {
const unsigned char *u = (unsigned char *)s;
size_t L = 0, R = strlen( s );
do {
while( L <= R && !isalpha(u[L]) && !isdigit(u[L]) ) L ;
while( L <= R && !isalpha(u[R]) && !isdigit(u[R]) ) R--;
} while( L <= R && tolower(u[L]) == tolower(u[R]) && (L =1) > 0 && (R-=1) > 0 );
return L >= R;
}
int main() {
/* same as above */
}