Reputation: 11
I have to write a function to check for palindromes in sentences and words.
For sentences it looks like this (and works):
int checkSentencepalindrome(char * str)
{
size_t len = strlen(str);
char *pntr1 = str;
char *pntr2 = str + len - 1;
while(pntr2 >= pntr1)
{
if (!isalpha(*pntr2))
{
pntr2--;
continue;
}
if (!isalpha(*pntr1))
{
pntr1++;
continue;
}
if(tolower(*pntr1) != tolower(*pntr2))
{
return 0;
}
pntr1++;
pntr2--;
}
return 1;
}
for word palindromes it looks like this:
int checkWordpalindrome(char * str)
{
size_t len = strlen(str);
char *pntr1 = str;
char *pntr2 = str + len - 1;
while(pntr2 >= pntr1)
{
if(tolower(*pntr1) != tolower(*pntr2))
{
return 0;
}
pntr1++;
pntr2--;
}
return 1;
}
However, the function for word palindromes returns me 0 all the time. (I expect a 1 for palindrome and 0 for non-palindrome words)
I thought the if statements I deleted are just there to skip spaces, exclamation marks, etc. (everything not included in the alphabet) Why are they so crucial for my function to work properly then?
How can I solve this while using pointers only?
EDIT: The issue only occurs when passing the string as following:
int checkWpalindrome(char * str)
{
printf("%s ", str);
size_t len = strlen(str);
if(len == 0)
{
return 0;
}
char *pntr1 = str;
char *pntr2 = str + len - 1;
while(pntr2 >= pntr1)
{
if(tolower(*pntr1) != tolower(*pntr2))
{
return 0;
}
pntr1++;
pntr2--;
}
return 1;
}
void input(char * str)
{
printf("Input: ");
fgets(str, 101, stdin);
fflush(stdin);
}
int main()
{
char arr[10];
input(arr);
printf("%d", checkWpalindrome(arr));
return 0;
}
Upvotes: 1
Views: 46
Reputation: 154243
fgets()
includes reading and saving a '\n'
and causes checkWordpalindrome()
to return 0 (unless maybe only "\n"
was read). @Adrian Mole.
To lop off the potential '\n'
, use str[strcspn(str, "\n")] = 0;
right after fgets()
.
Both functions risk undefined behavior (UB) as they can attempt to generate a pointer to before str
. Consider check...("?")
.
In checkSentencepalindrome()
the UB is is more so as code then attempts *pntr2
of an invalid pointer.
isalpha(ch)
and tolower(ch)
have (UB) when ch < 0
(and not EOF
)
Calling code buffer too small: char arr[10]; ... fgets(str, 101, stdin);
. Make them the same size like char arr[101]; ... fgets(str, 101, stdin);
fflush(stdin);
is UB and not needed. @Adrian Mole
Repaired code:
int checkSentencepalindrome(const char * str) {
size_t len = strlen(str);
const unsigned char *left = (const unsigned char *) str;
const unsigned char *right = left + len; // point one-past
while(left < right) {
if (!isalpha(right[-1])) {
right--;
continue;
}
if (!isalpha(left[0])) {
left++;
continue;
}
right--;
if (tolower(left[0]) != tolower(right[0])) {
return 0;
}
left++;
}
return 1;
}
A bit tidier with
while(left < right) {
if (!isalpha(*left)) {
left++;
continue;
}
right--;
if (!isalpha(*right)) {
continue;
}
if (tolower(*left) != tolower(*right)) {
return 0;
}
left++;
}
Upvotes: 0