简体   繁体   English

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

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

I wrote a small code piece of code in C to test strncmp() , memcmp() functions.我在 C 中写了一小段代码来测试strncmp()memcmp()函数。 Here is the code.这是代码。

#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;
}

I found strncmp(s1, s2, 8) = 0 while memcmp(s1, s2, 8) = -97 .我发现strncmp(s1, s2, 8) = 0memcmp(s1, s2, 8) = -97 Because \0 is not equal to a , I think strncmp(s1, s2, 8) should return a non-zero value.因为\0不等于a ,我认为strncmp(s1, s2, 8)应该返回一个非零值。

Then I tried to print s1 and s2 lengths, both of them are 9. And I tried to test more cases, strncmp() works as expected.然后我尝试打印s1s2长度,它们都是 9。我尝试测试更多案例, strncmp()按预期工作。

Finally, I tried a similar case as s1 and s2 , strncmp returns a fault value.最后,我尝试了与s1s2类似的情况, strncmp返回错误值。 The following is my code:以下是我的代码:

#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;
}

I guess maybe strncmp() will not compare characters after it meets \0 ?我想也许strncmp()在遇到\0后不会比较字符? Isn't that how strcmp works.这不是strcmp的工作原理。 I'm not sure that strncmp() works like strcmp() .我不确定strncmp()是否像strcmp()一样工作。

per the man pages, your suspicion is correct:根据手册页,您的怀疑是正确的:

Because strncmp() is designed for comparing strings rather than binary data, characters that appear after a `\0' character are not compared.因为 strncmp() 是为比较字符串而不是二进制数据而设计的,所以不会比较出现在 `\0' 字符之后的字符。

concatenating two null-terminated strings as a single string with two null characters will only result in the first portion being displayed (i think?).将两个以 null 结尾的字符串连接为一个带有两个 null 字符的字符串只会导致显示第一部分(我认为?)。

play

I guess maybe strncmp() will not compare characters after it meets \0 ?我想也许strncmp()在遇到\0后不会比较字符?

Yes, this is correct.是的,这是正确的。

Isn't that how strcmp works.这不是strcmp的工作原理。 I'm not sure that strncmp() works like strcmp() .我不确定strncmp()是否像strcmp()一样工作。

strcmp() compares two null-terminated byte string. strcmp()比较两个以 null 结尾的字节字符串。

strncmp() compares not more than count characters (characters that follow a null character are not compared) [where count is the third argument passed to strncmp() ] . strncmp()比较不超过count字符(不比较 null 字符后面的字符) [其中count是传递给strncmp()的第三个参数]

For eg:例如:

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

The following statements will do exactly same comparison ie both will compare first 5 characters and return the result 0 (contents of both the strings are same) because the first 5 characters in both the string is same and 5 th character is null character ( \0 ):以下语句将进行完全相同的比较,即两者都将比较前5字符并返回结果0 (两个字符串的内容相同),因为两个字符串中的前5个字符相同,第5字符是 null 字符( \0 ):

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

strncmp() will produce same result for the third argument value 7 , 6 and 5 passed to it. strncmp()将为传递给它的第三个参数值765产生相同的结果。

But consider following case:但考虑以下情况:

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

In this case, though, both will return 0 (same strings) but the comparison performed by strncmp() and strcmp() is different.但是,在这种情况下,两者都将返回0 (相同的字符串),但strncmp()strcmp()执行的比较是不同的。 strncmp() will compare only first 4 characters, whereas, strcmp() will compare till it finds null character. strncmp()将仅比较前4字符,而strcmp()将比较直到找到 null 字符。 Same for third argument value 3 , 2 , 1 and 0 passed to strncmp() .传递给strncmp()的第三个参数值3210相同。

Take another example:再举一个例子:

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

strcmp (s1, s2) will never return equal for these strings, but strcmp (s1, s2)永远不会为这些字符串返回相等,但是
strncmp (s1, s2, 5 /*or 4/3/2/1/0 */) will compare them equal. strncmp (s1, s2, 5 /*or 4/3/2/1/0 */)将比较它们相等。

Another point,还有一点,

Then I tried to print s1 and s2 lengths, both of them are 9.然后我尝试打印 s1 和 s2 的长度,它们都是 9。

Note that, sizeof does not give length but it gives the size of the object (or type) in bytes.请注意, sizeof没有给出长度,但它给出了 object(或类型)的大小(以字节为单位)。 If you want to calculate the length of a string, use strlen() .如果要计算字符串的长度,请使用strlen()


Couple of points to remember:要记住的几点:

1). 1)。 strncmp() does not compare characters following the null character. strncmp()不比较 null 字符之后的字符。

2). 2)。 One of the main difference between memcmp() and strncmp() is that strncmp() honour 1) the null character while doing comparison but memcmp() doesn't. memcmp()strncmp()之间的主要区别之一是strncmp()在进行比较时尊重1) null 字符,但memcmp()没有。

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

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