【问题标题】:strcmp says seemingly identical string are not equalstrcmp 表示看似相同的字符串不相等
【发布时间】:2019-02-08 20:55:23
【问题描述】:

我正在使用strcmp 来比较两个字符串。 lhs 来自通过fgets 的文件流。 rhs 是由 for 循环生成的 n-1 空格序列。


示例

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

int main() {
  size_t n = 10;
  char rhs[n];

  memset(rhs, ' ', n - 1); // Fill with spaces using memset()
  rhs[n-1] = 0; // Add NUL terminator

  printf("len=%zu\n", strlen(rhs));

  char lhs[n];

  FILE* file = fopen("test", "r");
  fgets(lhs, sizeof(lhs), file);
  printf("read=%s\n", lhs);

  return 0;
}


使用 gdb 时,我会发现我有两个看起来相同的字符串(为此我使用了 gdb 的 print):

lhs = " "

rhs = " "

然而,strcmp(lhs, rhs) != 0。这应该返回一个0,表明字符串是相同的,但是我得到了一些其他的非零值。

为什么这些字符串不相等?

【问题讨论】:

  • 打印出char 中的每个lhsrhs 最多n-1 字符,看看它们之间哪个不同。顺便说一句,您说lhsfgets 读取,但您的伪代码显示rhs 被读取。您应该展示您的真实代码,而不是伪代码。
  • rhs 的大小为n-1,但您尝试将n 字节读入其中。不会很顺利。
  • null 终结符在哪里?
  • fgets() 也会留下尾随的换行符,如果它读取的行上有一个。您如何查看您的字符串内容?
  • 请注意,fgets 保留了在比较之前必须删除的换行符。

标签: c strcmp


【解决方案1】:

输入到缓冲区的字符串不完全相同,并且您忽略添加空终止符意味着字符串程序将继续将字符串读取到缓冲区中,直到找到空终止符,运行以下代码显示我们这个:

size_t n = 5;
char lhs[n];
char rhs[n];
for(int i = 0; i < n-1; i++)
    rhs[i] = ' ';
for(int i = 0; rhs[i]; i++)
    printf("| %d ", rhs[i]);

输出:

| 32 | 32 | 32 | 32 |未知值...,可能是 0,但在那之前仍然是数组的一部分

您应该将数组视为内存地址,尤其是在将其传递给函数时

你应该这样写:

for(int i = 0; i < n-1; i++)
    rhs[i] = ' ';
rhs[n-1] = '\x00'; // null terminator

【讨论】:

    【解决方案2】:

    清理此代码以创建一个完整的最小示例,如下所示:

    #include <string.h>
    #include <stdio.h>
    
    int main() {
      size_t n = 10;
      char rhs[n];
    
      memset(rhs, ' ', n - 1); // Fill with spaces using memset()
      rhs[n-1] = 0; // Add NUL terminator
    
      printf("len=%zu\n", strlen(rhs));
    
      char lhs[n];
    
      FILE* file = fopen("test", "r");
      fgets(lhs, sizeof(lhs), file);
      printf("read=%s\n", lhs);
    
      return 0;
    }
    

    此处fgets 分配很重要,如果您打开了-Wall,这是一个警告。

    【讨论】:

    • 感谢您的清理。我终于明白了一个真正完整的、最小的例子现在是什么样子的。正如其他人所建议的那样,缺少空终止符是我的问题。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 2017-07-31
    相关资源
    最近更新 更多