Implementing a case-insensitive string comparison in C++ requires a bit more work than in some other languages, but it's certainly doable. Here's an efficient way to create a case-insensitive comparison function for std::string
:
#include <iostream>
#include <string>
#include <algorithm>
#include <cctype>
bool iequals(
const std::string& a, const std::string& b
) {
return std::equal(
a.begin(), a.end(), b.begin(), b.end(),
[](char a, char b) {
return std::tolower(
static_cast<unsigned char>(a)) ==
std::tolower(static_cast<unsigned char>(b));
}
);
}
int main() {
std::string str1{"Hello, World!"};
std::string str2{"hElLo, wOrLd!"};
std::string str3{"Hello, Universe!"};
std::cout << std::boolalpha;
std::cout << "str1 == str2 (case-sensitive): "
<< (str1 == str2) << '\n';
std::cout << "str1 == str2 (case-insensitive): "
<< iequals(str1, str2) << '\n';
std::cout << "str1 == str3 (case-insensitive): "
<< iequals(str1, str3) << '\n';
}
str1 == str2 (case-sensitive): false
str1 == str2 (case-insensitive): true
str1 == str3 (case-insensitive): false
Let's break down the iequals()
 function:
std::equal()
to compare the strings character by character.[](char a, char b) { ... }
compares each pair of characters.std::tolower()
from <cctype>
converts each character to lowercase before comparison.static_cast<unsigned char>
to avoid undefined behavior with negative char values.This method is efficient because it stops at the first mismatch and doesn't create any temporary strings.
For more complex scenarios, like locale-aware comparisons, you might want to use the <locale>
 library:
#include <locale>
bool iequals_locale(
const std::string& a, const std::string& b,
const std::locale& loc = std::locale()
) {
return std::equal(
a.begin(), a.end(), b.begin(), b.end(),
[&loc](char a, char b) {
return std::tolower(a, loc) ==
std::tolower(b, loc);
}
);
}
This version respects the locale settings, which can be important for certain languages.
Remember, these methods work well for ASCII strings, but may not handle Unicode correctly. For proper Unicode support, consider using a dedicated Unicode library like ICU.
If you need to do many comparisons against a single string, you might want to create lowercase versions of the strings first and then compare those:
std::string to_lower(std::string s) {
std::transform(
s.begin(), s.end(), s.begin(),
[](unsigned char c) {
return std::tolower(c);
}
);
return s;
}
// Usage:
std::string lower1 = to_lower(str1);
std::string lower2 = to_lower(str2);
bool equal = (lower1 == lower2);
This can be more efficient if you're doing multiple comparisons, as you only lowercase each string once.
Answers to questions are automatically generated and may not have been reviewed.
std::string
ClassA detailed guide to std::string
, covering the most essential methods and operators