简体   繁体   English

在C中使用memcmp比较两个字符串

[英]Comparing two strings using memcmp in c

Consider the following code: 考虑以下代码:

char str1[] = "Hello";
char str2[] = "Hello\0\0\0l\0o";
int x;
x=memcmp(str1,str2,sizeof(str2));
printf("%d",x);

When I run it, it shows the o/p as: 当我运行它时,它将o / p显示为:

1

Can you explain the reason for this. 您能解释一下原因吗? I learned that each byte in both strings are compared and returns accordingly. 我了解到,两个字符串中的每个字节都进行了比较并相应地返回。 But I am not clear about what happens at the end. 但是我不清楚最终会发生什么。

Your program invokes undefined behavior. 您的程序调用未定义的行为。

sizeof(str2) is larger than sizeof(str1) . sizeof(str2)大于sizeof(str1) By using that as the last argument to memcmp , you are accessing memory that you are not supposed to. 通过将其用作memcmp的最后一个参数,您可以访问不应该使用的内存。 That is cause for undefined behavior. 这是导致未定义行为的原因。

Hence, the output can be anything. 因此,输出可以是任何东西。 It's pointless trying to make sense of it. 试图理解它是没有意义的。

when you do string compare, it will stop comparing once it reaches '\\0'. 当您进行字符串比较时,一旦达到“ \\ 0”,它将停止比较。 In here you've done a memcmp, which will not stop until all the requested chars are read. 在这里,您已经完成了memcmp,直到读取所有请求的字符后,它才会停止。

In this case you're comparing sizeof(str2) bytes, which in the case of str1 will give garbage after the implied '\\0' at the end. 在这种情况下,您正在比较sizeof(str2)个字节,在str1的情况下,这将在最后的隐含'\\ 0'之后产生垃圾。

To get a 0 on the comparison: 要在比较中获得0:

  • compare only sizeof(str1) or sizeof(str1)+1 bytes 仅比较sizeof(str1)或sizeof(str1)+1个字节
  • do a string compare 做一个字符串比较

Remember, it is unsafe and sometimes danger to call memcmp here because str1 has fewer length than str2. 请记住,在此处调用memcmp不安全的 ,有时会有危险 ,因为str1的长度小于str2的长度。

Consider the following code: 考虑以下代码:

int main()
{
    char str1[] = "Hello";
    char str2[] = "AAAAA\0\0\0l\0o";
    for(int i=0; i<sizeof(str2); i++)
        printf("%02X %02X\n", str1[i], str2[i]);
    printf("\n%X %X", (int)str1, (int)str2);
    return 0;
}

The output is 输出是

48 41
65 41
6C 41
6C 41
6F 41
00 00
41 00
41 00
41 6C
41 00
41 6F
00 00

28FEEE 28FEF4

We can see the [6]-[11] bytes of str1 is actually the first bytes of str2 , and it could be confirmed by the address of str1 and str2 . 我们可以看到str1的[6]-[11]个字节实际上是str2的第一个字节,可以通过str1str2的地址来确认。 In the case, GCC/MSVC (I'm not very sure about Clang) store the two string const initalizer in a row. 在这种情况下,GCC / MSVC(我不太了解Clang)将两个字符串const初始化器连续存储。 So when you call memcmp , after the null-terminator \\0 , the function actually compares the first byte of str2 with \\0 . 因此,当您调用memcmp ,在空终止符\\0 ,该函数实际上会将str2的第一个字节与\\0 But remember, the way compiler stores constant may change under any circumstance. 但是请记住,编译器存储常量的方式在任何情况下都可能发生变化。 You should not rely on this behavior. 应该依赖于这种行为。

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

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