• ppal.c

  • §

    Jonas Altrock ew20b126@technikum-wien.at

    To overview.

    The whole source file ppal.c.

    /* compile with `clang -std=c99 -Wall -o ppal ppal.c` */
  • §

    Include C-libraries for input/output and allocation of memory.

    #include <stdio.h>
    #include <stdlib.h>
  • §

    Task

  • §

    Read a string and find out whether it is a palindrome. Use pointer arithmetics.

    Solution

  • §

    Pre-processor macro that defines the length of our input buffer. The longest we will read in is 80 characters, plus 1 for null-termination.

    #define MAX_CHARS_WITH_NUL 81
  • §

    main() takes no arguments for this program.

    int main() {
  • §

    calloc initializes the memory to all 0s, so we always have a null-terminated string.

        char *buffer = calloc(MAX_CHARS_WITH_NUL, sizeof(char));
        char c;
        int length = 0;
  • §

    Read in one character at a time, until newline. This is written a bit complicated, because we use the assignment to c as an expression here by wrapping it in parentheses.

    Usually it is not good style to have a side-effect like this (side-effect meaning the program state changes) in a context where we are asking a question and want a true or false answer. It can cause bugs due to being sensitive to the order in which the parts of the condition are evaluated.
        while ((c = getchar()) != '\n' && length < MAX_CHARS_WITH_NUL) {
  • §

    Ignore everything that is not a-z.

            if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
  • §

    If it is an uppercase character, transform it to lowercase.

                if ((c >= 'A' && c <= 'Z')) {
  • §

    Lowercase a-z are exactly 32 positions above the uppercase variants, see man ascii.

                    c += 32;
                }
    
                buffer[length] = c;
                length += 1;
            }
        }
  • §

    Now to check whether the input string is a palindrome. By default we assume it is a palindrome, until we find a contradiction.

        int is_palindrome = 1;
  • §

    Empty string and single char are palindromes. For everything longer than 1 char we use two pointers, from the start and end of the string, and move them towards each other until they meet.

        if (length > 1) {
            char *left, *right;
            left = buffer;
            right = buffer + (length - 1);
  • §

    Iterate until pointers meet or go past each other.

            while (left < right) {
  • §

    If the characters at the mirrored positions are unequal, we know we do not have a palindrome.

                if (*left != *right) {
                    is_palindrome = 0;
                }
    
                left += 1;
                right -= 1;
            }
        }
  • §

    Print the result.

        if (is_palindrome) {
            printf("palindrome\n");
        } else {
            printf("not a palindrome\n");
        }
  • §

    Don’t forget to free the allocated memory.

        free(buffer);
        return 0;
    }