C
Completed
-
Section 1: Getting Started
-
Section 2: Core Syntax
-
Section 3: Functions
-
Section 4: Arrays and Strings
-
Section 5: Pointers
-
Section 6: Memory Management
-
Section 7: Structures and Unions
-
Section 8: The Preprocessor and Build Process
-
Section 9: Standard Library: stdio.h
-
Section 10: Standard Library: stdlib.h
-
Section 11: Standard Library: string.h
-
Section 12: Standard Library: ctype.h and wctype.h
-
Section 13: Standard Library: math.h, complex.h, fenv.h, tgmath.h
-
Section 14: Standard Library: Type and Limit Headers
-
Section 15: Standard Library: Error Handling and Debugging
-
Section 16: Standard Library: Localization and Encoding
-
Section 17: Standard Library: time.h
-
Section 18: Standard Library: Concurrency (C11)
-
Section 19: POSIX and System Programming (unistd.h)
-
Section 20: More Data Structures
-
Section 21: Algorithms in C
-
Section 22: Bitwise Operations
-
Section 23: Command-Line Programs
-
Section 24: Debugging and Best Practices
-
Section 25: Compiler and Language Internals
-
Section 26: Embedded and Cross-Platform Considerations
-
Section 27: Networking Basics
-
Section 28: Practical Projects
-
Section 29: Interview Practice
-
Section 30: C23 Modern Features
-
Section 31: More Practice and Review
97: String Comparison: strcmp, strncmp
I was working on a small CLI tool the other day and I wanted to trigger a specific action if the user typed the word "admin". Coming from higher-level languages, my muscle memory kicked in, and I wrote something like this:
char input[] = "admin";
if (input == "admin") {
printf("Access granted!\n");
}
The pointer trap
I ran it, typed "admin", and... nothing. The program just sat there. To a beginner, this looks like a bug in the compiler, but for us, it's a classic C rite of passage. When I use == with strings, I'm not actually comparing the letters 'a', 'd', 'm', 'i', 'n'. I'm comparing the memory addresses of where those strings live.
The array input is at one spot in memory, and the string literal "admin" is stored in a read-only section of the binary elsewhere. They will never be the same address, so the expression is always false. To actually look at the characters, I need to use strcmp from <string.h>.
The zero-result confusion
I swapped the logic to use strcmp, but I hit another snag. I wrote it like this:
if (strcmp(input, "admin")) {
printf("Access granted!\n");
}
Oddly, it now prints "Access granted!" when I type "guest", and stays silent when I type "admin". This is where C gets a bit quirky. In most languages, a "true" result from a comparison is 1. But strcmp doesn't return a boolean; it returns the difference between the strings.
If the strings are identical, the difference is 0. In C, 0 is treated as false. So, by saying if (strcmp(...)), I was actually telling the program: "If these strings are different, grant access." To fix this, I have to explicitly check for zero:
if (strcmp(input, "admin") == 0) {
printf("Access granted!\n");
}
Putting a leash on the comparison
Now, strcmp is fine for simple cases, but it has a blind spot: it keeps reading memory until it hits a null terminator (\0). If you're dealing with data from a network socket or a corrupted file that's missing that null terminator, strcmp will just keep sailing past the end of your buffer, reading garbage until it crashes or finds a random zero in memory. That's a security vulnerability waiting to happen.
To prevent this, I prefer strncmp. The 'n' stands for the number of characters to check. I can tell it exactly when to stop:
char input[10] = "admin_user";
// I only care if the first 5 characters are "admin"
if (strncmp(input, "admin", 5) == 0) {
printf("You have admin privileges.\n");
}
This is much safer. Even if input wasn't properly null-terminated, strncmp stops after 5 characters. It's a small change in the function name, but it's a massive change in how robust your code is.
Sorting and ASCII values
One last thing I noticed: strcmp isn't just for equality. If it doesn't return 0, it returns a positive or negative integer. For example, if I compare "apple" and "banana", it returns a negative number because 'a' comes before 'b' in the ASCII table.
strcmp(s1, s2) == 0: The strings are identical.strcmp(s1, s2) < 0: s1 comes before s2 alphabetically.strcmp(s1, s2) > 0: s1 comes after s2 alphabetically.
This is why it's called a "comparison" function and not just an "equals" function—it's the foundation for how you'd write a sorting algorithm for a list of names.
📋 Practical Task
The Protocol Header Validator
You are writing a parser for a custom network protocol. Every valid packet must start with the header "PROT_V1:". However, the packets can be of varying lengths and might be malformed (missing null terminators).
Write a program that:
- Defines a character array
packet[]containing a simulated packet (e.g.,"PROT_V1:DATA_PAYLOAD"). - Uses
strncmpto check if the first 8 characters of the packet match the required header"PROT_V1:". - Prints "Valid Packet" if it matches, and "Invalid Protocol" if it does not.
- As a second test, change the
packetcontent to"PROT_V2:DATA_PAYLOAD"and ensure your program correctly identifies it as invalid.
There are no comments for now.