How to remove spaces and check if a string is a palindrome?
There are two-parts to your question: (1) "How to remove spaces"? and (2) [How to] "check if a string is a palindrome?". You should approach the problem in two discrete steps.
Removing whitespace from a string can be done in one of two different ways, (1) remove spaces in-place in the original string (presuming your original is a mutable string and not a String Literal) or (2) remove spaces while filling a second string with the non-whitespace characters from the first, preserving the first string unchanged (works regardless of whether the original is mutable). Your safest choice is the latter.
A simple function that provides the source and destination buffers as parameters to the function to remove whitespace could be as simple as:
void removespace (char *dest, const char *src)
{
size_t n = 0;
while (*src) {
if (!isspace(*src))
dest[n++] = *src;
src++;
}
dest[n] = *src; /* nul-terminate */
}
Moving to the second part of your problem, if you are having problems wrapping your head around using a start and end pointer to iterate from the ends of the string to the middle to check if the string is a palindrome, you can do the same thing with string indexes. Also, whenever you need to check whether something is whitespace or convert between character case, use the macros isspace()
or tolower() / toupper()
provided in ctype.h
. (otherwise YOU are responsible for ALL the conditional checks required)
A simple checkpalindrome()
implementation using string indexes could be:
int checkpalindrome (const char *s)
{
size_t n = 0, len = strlen (s);
while (len-- > n) /* loop over each start/end lowercase char */
if (tolower (s[n++]) != tolower (s[len]))
return 0;
return 1;
}
Now on your implementation of main()
reading your string from the user Never, ever, ever use gets()
. It is so insecure and so prone to exploit by buffer-overrun it has been removed from the standard library in C11. See Why gets() is so dangerous it should never be used!. Just use fgets()
instead and trim the line-ending from the buffer filled by fgets
by overwriting the line-ending with the nul-terminating character. (strcspn()
is convenient for this).
Putting it altogether (and using your ternary to control the "is"
or "is not"
output) you could do:
#include <stdio.h>
#include <string.h>
#include <ctype.h>
#define MAXC 1024 /* if you need a constant, define one (or more) */
void removespace (char *dest, const char *src)
{
size_t n = 0;
while (*src) {
if (!isspace(*src))
dest[n++] = *src;
src++;
}
dest[n] = *src; /* nul-terminate */
}
int checkpalindrome (const char *s)
{
size_t n = 0, len = strlen (s);
while (len-- > n) /* loop over each start/end lowercase char */
if (tolower (s[n++]) != tolower (s[len]))
return 0;
return 1;
}
int main (void) {
char s[MAXC], nospace[MAXC];
fputs ("enter a string: ", stdout);
if (!fgets (s, MAXC, stdin)) { /* Never, Ever use gets() */
fputs ("(user canceled input)\n", stderr);
return 1;
}
s[strcspn (s, "\r\n")] = 0; /* trim line-ending */
removespace (nospace, s); /* remove whitespace from s */
printf ("'%s' => %s a palindrome.\n",
s, checkpalindrome (nospace) ? "is" : "is not");
return 0;
}
(note: Never Skimp on Buffer Size!)
Example Use/Output
$ ./bin/checkpalindrome
enter a string: a
'a' => is a palindrome.
(you can change how you handle a single character string to fit your needs)
$ ./bin/checkpalindrome
enter a string: aa
'aa' => is a palindrome.
$ ./bin/checkpalindrome
enter a string: ab
'ab' => is not a palindrome.
$ ./bin/checkpalindrome
enter a string: aba
'aba' => is a palindrome.
$ ./bin/checkpalindrome
enter a string: abc
'abc' => is not a palindrome.
$ ./bin/checkpalindrome
enter a string: A man a plan a canal Panama
'A man a plan a canal Panama' => is a palindrome.
Look things over and let me know if you have questions.