比较字符串忽略 NUL

Posted

技术标签:

【中文标题】比较字符串忽略 NUL【英文标题】:Compare strings ignore NUL 【发布时间】:2019-02-11 16:24:43 【问题描述】:

我正在尝试比较两个 std::strings"abc\0""abc"。 有没有办法在比较时忽略一个字符,在这种情况下是 '\0' (NUL)?

现在我正在对带有尾随 NUL 的字符串执行pop_back() 来删除它,但必须有更好的方法来处理这个问题。

【问题讨论】:

可以将 C 字符串与 C 字符串比较函数(strcmp 等)进行比较,这会忽略 \0。不过我还是更喜欢你现在的方法。 NUL 最初是如何进入其中的?这就是我要解决的问题。 @SombreroChicken 更准确地说:它不会忽略,它会在第一个空字符处停止 - 所以 "ab\0c" 和 "abc" 也不会比较相等。如果它只是在最后,虽然(pop_back!)...... @NeilButterworth:无关紧要。 NUL 字符在 std::string 中完全有效。 @NicolBolas 虽然 NUL 字符在 std::string 中完全有效,但根据问题,这似乎不是预期的 【参考方案1】:

如果空终止符总是在末尾,您可以使用std::strcmp

否则你可以自己编写循环来迭代两个字符串并比较字符,遇到终止符时有特殊规则。

可以完全使用标准算法来实现效率较低的版本:创建每个字符串的副本,删除终止符 (std::copy_if),然后使用 std::string 的比较运算符。

【讨论】:

【参考方案2】:

如果您要比较两个字符串,一个长度为 4 "abc\0" 和一个长度为 3 "abc",当然它们不会比较相等。其中一个字符是 NUL 的事实与此无关。

如果您想查看一个字符串是否与另一个字符串相同,只是最后嵌入了 NUL - 可以这样写:

std::string s1"abc\0", 4;
std::string s2"abc"  , 3;
return s2.length() == s1.length() - 1 && // sizes differ by one char
       s1.back() == '\0' &&              // last char is a NUL
       s1.compare(0, s1.length() - 1, s2) == 0; // all the other ones are the same

【讨论】:

【参考方案3】:

与 C 风格的字符串不同,NULstd::string 的有效字符,不会与其他字符有任何区别。

因此,如果您的某个std::strings 后缀为NUL 字符,而这不是您想要的,您最好弄清楚为什么首先包含NUL

如果您无法找到源并修复它,有两种通用的解决方法。

(1)在比较前修剪字符串

您可以使用来自第三方库的trim()-like 函数,例如促进;或编写您自己的实现。

此函数只是删除NUL 字符。

(2) 比较 C-Style 中的字符串

使用std::string::c_str()获取c风格的字符串,然后使用strcmp等函数进行比较。

请注意,如果字符串中间有一个NUL 字符,例如ab\0c,则此解决方法会为您提供不正确的结果。

【讨论】:

以上是关于比较字符串忽略 NUL的主要内容,如果未能解决你的问题,请参考以下文章

AC日记——忽略大小写的字符串比较 openjudge 1.7 16

如何在忽略大小写的sql中比较字符串?

3. 忽略大小写的字符串比较

与BERT的字符串比较似乎忽略了句子中的“not”

SQL 字符串比较 - 如何忽略空格

比较字符串忽略开头或结尾处的空格