如何比较两个字符串中可以有空字符?

问题描述 投票:0回答:2

我想比较两个字符串 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 最终给出相等,并跳过之后的比较。 我可以使用任何库来比较这些字符串

c++ strcmp
2个回答
2
投票

区分大小写的比较很简单:

// 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
可能为负值。


0
投票

这个:

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) {
    ...
}
© www.soinside.com 2019 - 2024. All rights reserved.