使用memcmp比较两个字符串文字

时间:2018-05-02 07:17:51

标签: c language-lawyer undefined-behavior string-literals memcmp

我使用memcmp函数比较了两个字符串文字。

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

int main() 
{
  char str1[] = "abcd";
  char str2[] = "ab";

  if (memcmp(str1, str2, 4) == 0) 
  {
    printf("equal string\n");
  }
  return 0;
}

在上述计划中,str2str1短。这意味着字符串str2的访问范围超出范围。

那么,这是不确定的行为吗?

2 个答案:

答案 0 :(得分:11)

您的代码行为未定义。一旦知道结果,C标准就不要求memcmp返回;即使\0'c'进行比较,它仍然不必 必须返回'c' == '\0'语言支持的字符编码。该标准也没有规定字典比较的顺序(尽管实现从一开始就很难实现)。

0str2类型。尝试访问第4个元素是可能的。

参考:http://en.cppreference.com/w/c/string/byte/memcmp

答案 1 :(得分:-2)

是的,您的代码行为未定义。但是,只要您使用if (memcmp(str1, str2, 3) == 0)(请注意字节数为3而不是4.即最少两个),您的代码行为将是可接受和正确的。

  

如果访问发生在lhs和rhs指向的任一对象的末尾之外,则行为未定义。如果lhs或rhs是空指针,则行为未定义。

如果是strcmp,它会在找到\0后立即停止。但是,对于memcmp,

  

这是一个有缺陷的假设,即memcmp逐字节比较并且不会查看超出第一个差异点的字节。 memcmp函数没有这样的保证。在报告比较结果之前,允许从两个缓冲区中读取所有字节。

所以,我会写这样的代码:

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

#define MIN(X, Y) (((X) < (Y)) ? (X) : (Y))

int main() 
{
  char str1[] = "abcd";
  char str2[] = "ab";
  int charsToCompare = MIN(strlen(str1), strlen(str2)) + 1;

  if (memcmp(str1, str2, charsToCompare) == 0) 
  {
    printf("equal string\n");
  }
  return 0;
}

memcmp可以找到'02/May/2018 09:41:21] "GET /static/css/design.css%25 HTTP/1.1" 404 1761' 的更多详情和分析。