我想比较两个字符串 s1 和 s2,两个字符串之间可以有空字符。 我想要区分大小写和不敏感的比较,如 strcmp 和 strcasecmp。 假设我的字符串是:
std::string s1="Abcd\0abcd"
std::string s2="Abcd\0cccc"
目前,我正在做 strcmp(s1.c_str(), s2.c_str()) 和 strcasecmp(s1.c_str(), s2.c_str()) 在这种情况下,strcasecmp 和 strcmp 最终给出相等,并跳过之后的比较。 我可以使用任何库来比较这些字符串
区分大小写的比较很简单:
// or use std::string prior to C++17
std::string_view s1 = "Abcd\0abcd";
std::string_view s2 = "Abcd\0cccc";
bool eq = s1 == s2; // false
std::string_view
已经不关心字符串中的空字符,因此您可以使用重载的==
运算符。
一般来说,您应该避免像 strcmp
这样的 C 函数; C++ 中有更好的替代方案,不需要以 null 结尾的字符串。
不区分大小写的比较稍微困难一些,但可以使用 std::ranges::equal
标题中的
std::equal
或
<algorithm>
轻松完成。
// C++20
bool eq = std::ranges::equal(s1, s2, [](unsigned char a, unsigned char b) {
return std::tolower(a) == std::tolower(b);
});
// legacy
bool eq = std::equal(std::begin(s1), std::end(s1), std::begin(s2), std::end(s2),
[](unsigned char a, unsigned char b) {
return std::tolower(a) == std::tolower(b);
});
注意:重要的是 lambda 接受
unsigned char
,而不是 char
;如果输入负值,std::tolower
将无法正常工作,并且char
可能为负值。
这个:
std::string s1="Abcd\0abcd"
将导致 std::string 被赋值
"Abcd"
,因为赋值将在字符串文字中的第一个空字符处停止。
这将包括带有空值的完整二进制字符串:
std::string s1("Abcd\0abcd", 9);
std::string s2=("Abcd\0cccc", 9);
然后你可以这样做:
if (s1 < s2) {
}
或不区分大小写:
auto s1lower = s1;
std::transform(s1lower.begin(), s1lower.end(), s1lower.begin(),
[](char c){ return std::tolower(c); });
auto s2lower = s2;
std::transform(s2lower.begin(), s2lower.end(), s2lower.begin(),
[](char c){ return std::tolower(c); });
if (s1lower < s2lower) {
...
}