Echo All Palindromes, in C Echo All Palindromes, in C unix unix

Echo All Palindromes, in C


Yes, I think that you are following the R&K advice. As Hugo said, you could take the argumentas a filename, bu,t IMHO, for this simple program, I'd say that taking the parameter as the palindrome itself may make more sense.

Also, if you allow me extra advice, I would separate the functionality of reading a string from checking whether it is a palindrome or not, because you have that code duplicated right now.

int ispalindrome(const char* c) {    size_t len = strlen(c);   size_t limit = len/2;   size_t i;   for (i = 0; i < limit; i++) {     if(c[i]!=c[len-i-1]) break; /* Different character found */   }   return i==limit; /* If we reached limit, it's a palyndrome */}

Of course, I am pretty sure this can be improved (it may even have a bug, I am typping quite fast), but once that you have your string, be either from command line or user input, you can call this function or a functiom like this.

NOTE: Edited to reflect comment from Mark, thanks a lot, Mark!


One problem that you have is a potential buffer overflow because you are writing an input of arbitrary length into a buffer with a fixed size. You can fix this by rejecting too long inputs or creating an array of the correct size dynamically. I would avoid using scanf.

Regarding the actual algorithm, you don't need to copy the string reversed and then compare the two strings. You could do the check using only a single copy of the string and a pointer at both ends, both moving in towards the middle.

Here is some code to show the principle:

char* a = /* pointer to first character in string */;char* b = /* pointer to last character in string (excluding the null terminator) */;while (a < b && *a == *b){    a++;    b--;}if (a >= b){    // Is palindrome.}

I agree with Javier that you factor the palindrome checking code out into a separate function.


Regarding the principles you specified, I believe that these tools usually take their arguments as filenames whose content is to be processed. Instead, you are treating them like the input itself.

Take sort, for example. If you don't specify any arguments, the contents from stdin will be sorted. Otherwise, the contents in the file whose filename you specified will be sorted. It is not the arguments themselves that are processed.

The code for this would be something along these lines:

FILE * input = stdin;if (argc > 1){  input = fopen(argv[1], "r");  // handle possible errors from the fopen}while (fscanf(input, "%s", i_string) != EOF)  // check if i_string is a palindrome and output to stdout

Also, you should be careful with the buffer overflow specified by Mark Byers.

You're not handling the string reading correctly. The i_string buffer is not initialized, and even if it were, you're should limit the number of bytes that scanf reads to avoid the mentioned overflow:

char i_string[1000];while (scanf("999%s", i_string) != EOF)  if (is_palindrome(i_string)) /* Use any function defined in the other answers */    printf("%s\n", i_string);

You must always reserve one more byte (1000 vs 999) to account for the NULL string terminator. If you want to allow arbitrary length strings, I think you'll have to dinamically allocate the buffer, and resize it in case bigger strings are present. This would be slightly more complicated.