Comparing or ordering two C-strings, especially for equality, can be confusing. Nevertheless, these operations are crucial for many text-processing programs. I believe there are three main reasons for the confusion. First, C++ has two kinds of strings, each with a different way of comparing or ordering them. The C++ string class supports the full set of C++ relational operators, ==
, !=
, <
, <=
, >
, and >=
, but C-strings do not. Second, we must use the strcmp function to compare C-strings, and its behavior can be hard to understand. Finally, neither C nor C++ has an "equals" function or operator for comparing C-strings for equality.
String Class Relationship | C-String strcmp Functions | A Common Error |
---|---|---|
s1 == s2 |
strcmp(s1, s2) == 0
!strcmp(s1, s2) |
char* s1 = "hello";
char* s2 = "hello";
if (s1 == s2)
cout << "Equal\n";
else
cout << "NOT equal\n"; |
s1 != s2 |
strcmp(s1, s2) != 0 strcmp(s1, s2) |
|
s1 < s2 |
strcmp(s1, s2) < 0 |
|
s1 <= s2 |
strcmp(s1, s2) <= 0 |
|
s1 > s2 |
strcmp(s1, s2) > 0 |
|
s1 >= s2 |
strcmp(s1, s2) >= 0 |
|
(a) | (b) | (c) |
NOT equal
to the console. We can use the equality operator to determine if two pointers point to the same C-string but not to determine if strings contain the same text.strcmp is an ordering function - given two strings, it imposes an order on them - specifying which one comes or orders first. The ordering is based on the ASCII collating sequence, which means that the characters are ordered based on their ASCII encoding (this ordering sequence is sometimes informally called asciibetical order). strcmp manages to provide for C-strings all of the functionality represented by the Java relational operators above.
strcmp: String-Compare
![]() |
(a) |
![]() |
(b) |
![]() |
(c) |
strcmp(s1, s2)
Return Values
#define <cstring>
int strcmp(const char* s1, const char* s2);
strcmp Function Calls | Return Values |
---|---|
strcmp("apple", "zebra") |
-1 |
strcmp("zebra", "apple") |
1 |
strcmp("apple", "apple") |
0 |
strcmp("APPLE", "apple") |
-1 |
strcmp("apple", "APPLE") |
1 |
strcmp("app", "apple") |
-1 |
strcmp("apple", "app") |
1 |
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> using namespace std; int main() { char* s1 = "HELLO WORLD"; char* s2 = "HELLO WORLD"; if (strcmp(s1, s2) == 0) cout << "They are equal\n"; else cout << "They are NOT equal\n"; if (!strcmp(s1, s2)) cout << "They are equal\n"; else cout << "They are NOT equal\n"; return 0; }
Output:
They are equal They are equal
!
, in the second highlighted example.
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> using namespace std; int main() { char* s1 = "HELLO world"; char* s2 = "HELLO WORLD"; if (strcmp(s1, s2) <= 0) cout << "s1, s2\n"; else cout << "s2, s1\n"; return 0; }
Output:
s2, s1
#define _CRT_SECURE_NO_WARNINGS #include <iostream> #include <cstring> using namespace std; int main() { char* s1 = "HELLO"; char* s2 = "HELLO WORLD"; if (strcmp(s1, s2) < 0) cout << "s1, s2\n"; else cout << "s2, s1\n"; return 0; }
Output:
s1, s2
int strcmp(const char* s1, const char* s2) { int i = 0; while (s1[i] != '\0' && s2[i] != '\0' && s1[i] == s2[i]) i++; if (s1[i] < s2[i]) return -1; else if (s1[i] > s2[i]) return 1; return 0; } |
int strcmp(const char* s1, const char* s2) { for (; *s1 && *s2 && *s1 == *s2; s1++, s2++) ; if (*s1 < *s2) return -1; else if (*s1 > *s2) return 1; return 0; } |
(a) | (b) |
The loops in both versions examine the strings' characters one at a time from left to right. The order of the sub-expressions in the test is significant. The tests for the strings' end (highlighted in yellow) occur before the equality test (in blue), and short circuit evaluation prevents the equality test from indexing the strings out of bounds. The loops end when they reach the end of either string or find two corresponding characters that don't match. The if-statement compares the two characters that caused the loop to end. If the strings are different lengths, then one of the characters is the null-terminator, which is the character equivalent of zero and less than any other character. The if-else ladder returns a value indicating the strings' ordering.