繁体   English   中英

为什么 `strncmp()` 在特殊情况下会返回错误值?

[英]Why `strncmp()` return a fault value in a special case?

我在 C 中写了一小段代码来测试strncmp()memcmp()函数。 这是代码。

#include <stdio.h>
#include <string.h>

int main()
{
    const char s1[] = "abcd\0\0\0\0";
    const char s2[] = "abcd\0abc";
    
    printf("strncmp(s1, s2, 4) = %d\n", strncmp(s1, s2, 5)); //0
    printf("strncmp(s1, s2, 8) = %d\n", strncmp(s1, s2, 8)); // why returns 0? Thx
    printf("memcmp(s1, s2, 4) = %d\n", memcmp(s1, s2, 5)); // 0
    printf("memcmp(s1, s2, 8) = %d\n", memcmp(s1, s2, 8)); // -120

    return 0;
}

我发现strncmp(s1, s2, 8) = 0memcmp(s1, s2, 8) = -97 因为\0不等于a ,我认为strncmp(s1, s2, 8)应该返回一个非零值。

然后我尝试打印s1s2长度,它们都是 9。我尝试测试更多案例, strncmp()按预期工作。

最后,我尝试了与s1s2类似的情况, strncmp返回错误值。 以下是我的代码:

#include <stdio.h>
#include <string.h>

int main()
{
    const char s1[] = "abcd\0\0\0\0";
    const char s2[] = "abcd\0xyz";
    
    printf("strncmp(s1, s2, 4) = %d\n", strncmp(s1, s2, 5)); //0
    printf("strncmp(s1, s2, 8) = %d\n", strncmp(s1, s2, 8)); // why returns 0? Thx
    printf("memcmp(s1, s2, 4) = %d\n", memcmp(s1, s2, 5)); // 0
    printf("memcmp(s1, s2, 8) = %d\n", memcmp(s1, s2, 8)); // -120

    printf("sizeof(s1) = %lu\n", sizeof(s1)); // 9
    printf("sizeof(s2) = %lu\n", sizeof(s2)); // 9

    printf("%d\n", strncmp("\0", "a", 1)); // -1
    printf("%d\n", strncmp("\0\0", "ab", 2)); // -1
    printf("%d\n", strncmp("a\0", "ab", 2)); // -1

    printf("%d\n", strncmp("a\0\0", "a\0b", 3)); // 0, why?

    return 0;
}

我想也许strncmp()在遇到\0后不会比较字符? 这不是strcmp的工作原理。 我不确定strncmp()是否像strcmp()一样工作。

根据手册页,您的怀疑是正确的:

因为 strncmp() 是为比较字符串而不是二进制数据而设计的,所以不会比较出现在 `\0' 字符之后的字符。

将两个以 null 结尾的字符串连接为一个带有两个 null 字符的字符串只会导致显示第一部分(我认为?)。

我想也许strncmp()在遇到\0后不会比较字符?

是的,这是正确的。

这不是strcmp的工作原理。 我不确定strncmp()是否像strcmp()一样工作。

strcmp()比较两个以 null 结尾的字节字符串。

strncmp()比较不超过count字符(不比较 null 字符后面的字符) [其中count是传递给strncmp()的第三个参数]

例如:

    const char s1[] = "abcd\0\0\0\0";
    const char s2[] = "abcd\0xyz";

以下语句将进行完全相同的比较,即两者都将比较前5字符并返回结果0 (两个字符串的内容相同),因为两个字符串中的前5个字符相同,第5字符是 null 字符( \0 ):

    strncmp (s1, s2, 8);
    strcmp (s1, s2);

strncmp()将为传递给它的第三个参数值765产生相同的结果。

但考虑以下情况:

    strncmp (s1, s2, 4); 
    strcmp (s1, s2);

但是,在这种情况下,两者都将返回0 (相同的字符串),但strncmp()strcmp()执行的比较是不同的。 strncmp()将仅比较前4字符,而strcmp()将比较直到找到 null 字符。 传递给strncmp()的第三个参数值3210相同。

再举一个例子:

    const char s1[] = "abcdef";
    const char s2[] = "abcde";

strcmp (s1, s2)永远不会为这些字符串返回相等,但是
strncmp (s1, s2, 5 /*or 4/3/2/1/0 */)将比较它们相等。

还有一点,

然后我尝试打印 s1 和 s2 的长度,它们都是 9。

请注意, sizeof没有给出长度,但它给出了 object(或类型)的大小(以字节为单位)。 如果要计算字符串的长度,请使用strlen()


要记住的几点:

1)。 strncmp()不比较 null 字符之后的字符。

2)。 memcmp()strncmp()之间的主要区别之一是strncmp()在进行比较时尊重1) null 字符,但memcmp()没有。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM