C Tutorial
C Project: Palindrome Checker
Test whether a string reads the same forwards and backwards, ignoring case.
What you will build
A palindrome reads the same forwards and backwards. radar is one. A single letter such asC is one. StudyGrid is not. The checker must ignore case so Radar andradar both count as yes.
C strings are char arrays that end with a null byte. You will use strlen from<string.h> and tolower from <ctype.h>. Compile withTry it in C at /c/try,.
Two indices, one string
Walk from both ends. Index i starts at 0. Index j starts at length minus one. Compare the characters. If they differ, the string is not a palindrome. If they match, move i up andj down until the indices meet.
Example
#include <stdio.h>
#include <string.h>
int main(void) {
char word[] = "radar";
int i = 0;
int j = (int)strlen(word) - 1;
int ok = 1;
while (i < j) {
if (word[i] != word[j]) {
ok = 0;
break;
}
i++;
j--;
}
printf("%s: %s\n", word, ok ? "yes" : "no");
return 0;
}This version is case-sensitive. Radar would fail because 'R' is not'r'. The next listing folds both sides to lowercase before comparing.
Ignore case with tolower
tolower expects a value that fits in unsigned char (or EOF). Cast each character before you call it. Compare the folded values, not the originals. The letters in the string stay unchanged; only the test is case-insensitive.
Example
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int is_palindrome(const char *s) {
int i = 0;
int j = (int)strlen(s) - 1;
while (i < j) {
unsigned char a = (unsigned char)s[i];
unsigned char b = (unsigned char)s[j];
if (tolower(a) != tolower(b)) {
return 0;
}
i++;
j--;
}
return 1;
}
int main(void) {
printf("%s\n", is_palindrome("Radar") ? "yes" : "no");
printf("%s\n", is_palindrome("grid") ? "yes" : "no");
return 0;
}You should see yes, then no. Run it in /c/try. The C editor uses gcc. It is not/try, /html/try, or /cpp/try.
Test radar, C, and StudyGrid
Put the required samples in an array of string pointers. Print yes or no for each. A one-character string is a palindrome because the two indices never pass each other: length 1 givesj == 0, so the loop body does not run and the function returns 1.
Example
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int is_palindrome(const char *s) {
int i = 0;
int j = (int)strlen(s) - 1;
while (i < j) {
unsigned char a = (unsigned char)s[i];
unsigned char b = (unsigned char)s[j];
if (tolower(a) != tolower(b)) {
return 0;
}
i++;
j--;
}
return 1;
}
int main(void) {
const char *samples[] = {"radar", "C", "StudyGrid"};
int n = (int)(sizeof samples / sizeof samples[0]);
for (int k = 0; k < n; k++) {
printf("%s: %s\n", samples[k], is_palindrome(samples[k]) ? "yes" : "no");
}
return 0;
}Expected output: radar yes, C yes, StudyGrid no. If StudyGrid prints yes, the indices are not moving, or you compared only the first character.
A few extra checks
Empty text is a palindrome by the same loop rule: length 0 makes j equal to -1, thewhile condition fails, and the function returns 1. Mixed-case palindromes such asRacecar should print yes only after tolower is in place.
Example
#include <stdio.h>
#include <string.h>
#include <ctype.h>
int is_palindrome(const char *s) {
int i = 0;
int j = (int)strlen(s) - 1;
while (i < j) {
unsigned char a = (unsigned char)s[i];
unsigned char b = (unsigned char)s[j];
if (tolower(a) != tolower(b)) {
return 0;
}
i++;
j--;
}
return 1;
}
int main(void) {
const char *samples[] = {
"radar", "C", "StudyGrid", "Racecar", "Ada", "",
};
int n = (int)(sizeof samples / sizeof samples[0]);
for (int k = 0; k < n; k++) {
const char *label = samples[k][0] == '\0' ? "(empty)" : samples[k];
printf("%s: %s\n", label, is_palindrome(samples[k]) ? "yes" : "no");
}
return 0;
}Common mistakes
- Comparing with
==on two arrays. That compares addresses. Walk characters, or usestrcmponly when you mean exact full-string equality. - Forgetting
tolower, soRadarfails. The lead for this project is case-insensitive. - Calling
toloweron a plaincharthat might be negative. Cast tounsigned charfirst. - Using
j = strlen(s)without subtracting one. Then the last index is the null terminator and every non-empty string fails.
Practice
- Skip spaces so a phrase such as
never odd or evencan count as a palindrome if you want that rule. - Print the length of each sample beside yes or no.
- Add
level,python, andAbBato the sample list and write the expected yes/no lines before you compile.