C Notes
Complete guide to comparing strings in C using strcmp, strncmp, case-insensitive comparison, and custom comparison functions with practical examples.
Comparing strings is one of the most frequent operations in any program — validating user input, sorting names alphabetically, matching passwords, or searching for keywords. Since C strings are character arrays, you cannot use == to compare their content (that only compares memory addresses). Instead, C provides dedicated comparison functions.
Why You Cannot Use == for Strings
This is perhaps the most common beginner mistake in C:
#include <stdio.h>
int main() {
char str1[] = "Hello";
char str2[] = "Hello";
// WRONG: Compares memory addresses, not content!
if (str1 == str2) {
printf("Equal (address)\n");
} else {
printf("Not equal (address)\n"); // This prints!
}
return 0;
}Not equal (address)
Even though both contain "Hello", they are stored at different memory locations, so == returns false.
| str1 | [H][e][l][l][o][\0] at address 0x1000 |
| str2 | [H][e][l][l][o][\0] at address 0x2000 |
| str1 == str2 | 0x1000 == 0x2000 → FALSE! |
strcmp() - Full String Comparison
How strcmp Works
strcmp compares strings character by character using ASCII values. It stops at the first difference or when both strings end.
int strcmp(const char *s1, const char *s2);Return values:
- 0 → strings are identical
- Negative → s1 < s2 (s1 comes first lexicographically)
- Positive → s1 > s2 (s1 comes after s2 lexicographically)
#include <stdio.h>
#include <string.h>
void compareAndPrint(const char *s1, const char *s2) {
int result = strcmp(s1, s2);
if (result == 0)
printf("\"%s\" == \"%s\"\n", s1, s2);
else if (result < 0)
printf("\"%s\" < \"%s\" (result: %d)\n", s1, s2, result);
else
printf("\"%s\" > \"%s\" (result: %d)\n", s1, s2, result);
}
int main() {
compareAndPrint("apple", "apple");
compareAndPrint("apple", "banana");
compareAndPrint("banana", "apple");
compareAndPrint("cat", "car");
compareAndPrint("hello", "hello world");
compareAndPrint("ABC", "abc");
return 0;
}"apple" == "apple" "apple" < "banana" (result: -1) "banana" > "apple" (result: 1) "cat" > "car" (result: 16) "hello" < "hello world" (result: -32) "ABC" < "abc" (result: -32)
Step-by-Step Comparison Process
| Position 0: 'c' vs 'c' | equal, continue |
| Position 1: 'a' vs 'a' | equal, continue |
| Position 2: 't' vs 'r' | different! |
| 't' (116) - 'r' (114) = +2 | return positive |
| Result | "cat" > "car" |
Practical Use: Sorting Strings
Before sorting: Charlie Alice Eve Bob Diana After sorting: Alice Bob Charlie Diana Eve
strncmp() - Compare First N Characters
When you only need to compare a prefix — like checking file extensions or command prefixes:
int strncmp(const char *s1, const char *s2, size_t n);#include <stdio.h>
#include <string.h>
int main() {
char filename[] = "report_2024.pdf";
// Check if file starts with "report"
if (strncmp(filename, "report", 6) == 0) {
printf("This is a report file.\n");
}
// Check file extension
char *ext = filename + strlen(filename) - 4;
if (strcmp(ext, ".pdf") == 0) {
printf("It's a PDF file.\n");
}
// Compare different strings with limit
printf("\nstrncmp(\"Hello\", \"Help\", 3) = %d\n", strncmp("Hello", "Help", 3));
printf("strncmp(\"Hello\", \"Help\", 4) = %d\n", strncmp("Hello", "Help", 4));
return 0;
}This is a report file.
It's a PDF file.
strncmp("Hello", "Help", 3) = 0
strncmp("Hello", "Help", 4) = -4Case-Insensitive String Comparison
C standard library doesn't include a case-insensitive comparison function, but most systems provide one (non-standard):
POSIX: strcasecmp
#include <stdio.h>
#include <strings.h> // Note: strings.h (with 's')
int main() {
// Available on Linux/macOS (POSIX)
printf("%d\n", strcasecmp("Hello", "HELLO")); // 0
printf("%d\n", strcasecmp("Apple", "banana")); // negative
return 0;
}Custom Implementation (Portable)
Compare "Hello" vs "HELLO": 0 Compare "Apple" vs "apple": 0 Compare "ABC" vs "abd": -1 User confirmed!
Lexicographic Order Explained
String comparison follows lexicographic order — dictionary ordering based on character codes:
| '0'-'9' | 48-57 |
| 'A'-'Z' | 65-90 |
| 'a'-'z' | 97-122 |
| Therefore | digits < uppercase < lowercase |
Comparison with memcmp
memcmp compares raw bytes without stopping at null terminators:
#include <stdio.h>
#include <string.h>
int main() {
char s1[] = "Hello\0World"; // Contains embedded null
char s2[] = "Hello\0Earth";
// strcmp stops at first '\0'
printf("strcmp: %d\n", strcmp(s1, s2)); // 0 (both = "Hello")
// memcmp compares all specified bytes
printf("memcmp(11): %d\n", memcmp(s1, s2, 11)); // Non-zero
return 0;
}strcmp: 0 memcmp(11): 1
Comparison Function Summary
| Function | Compares | Stops at '\0'? | Case-sensitive? | Standard? |
|---|---|---|---|---|
strcmp | Full strings | Yes | Yes | C89+ |
strncmp | First n chars | Yes | Yes | C89+ |
strcasecmp | Full strings | Yes | No | POSIX |
strncasecmp | First n chars | Yes | No | POSIX |
memcmp | n bytes | No | Yes | C89+ |
Interview Questions
Q1: What does strcmp return when comparing "abc" with "abcd"?
It returns a negative value. When all characters of the shorter string match the beginning of the longer string, strcmp compares the null terminator '\0' (value 0) of "abc" with 'd' (value 100) in "abcd", resulting in 0 - 100 = -100.
Q2: Why should you use strncmp instead of strcmp in security-sensitive code?
strncmp bounds the comparison length, preventing potential issues with unterminated strings or timing attacks. It's also useful when you only need to check a prefix (like a command name) without caring about the rest.
Q3: How does locale affect string comparison?
strcmp uses raw byte values (ASCII/UTF-8) and is locale-independent. For locale-aware comparison (proper alphabetical ordering in different languages), use strcoll() which respects the current locale settings.
Q4: Implement a version of strcmp that compares strings in reverse order.
Compare from the last characters moving backward. First find both lengths, then compare from len-1 toward 0. If lengths differ and all compared characters match, the longer string is "greater".
Summary
- Never use
==to compare strings — it compares addresses, not content strcmpreturns 0 for equality, negative if s1 < s2, positive if s1 > s2strncmplimits comparison to first N characters — useful for prefix matching- Case-insensitive comparison requires
strcasecmp(POSIX) or a custom function - Lexicographic order is based on ASCII values: digits < uppercase < lowercase
memcmpcompares raw bytes and doesn't stop at null terminators
Exam Focus
Revise definitions, diagrams, examples, and short-answer points for String Comparison in C - strcmp, strncmp, Case-Insensitive.
Interview Use
Prepare one clear explanation, one practical example, and one common mistake for this C Programming topic.
Search Terms
c-programming, c programming, programming, strings, string, comparison, string comparison in c - strcmp, strncmp, case-insensitive
Related C Programming Topics