strcmp 表示看似相同的字符串不相等
strcmp says seemingly identical string are not equal
我正在使用 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
。这应该 return 一个 0
表明字符串是相同的,但我得到了一些其他非零值。
为什么这些字符串不相等?
输入缓冲区的字符串不完全相同,您忽略添加空终止符意味着字符串程序将继续将字符串读入缓冲区,直到找到空终止符,运行 下面的代码向我们展示了这一点:
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 | unknown values ..., could be 0, but until then still part of the array
您应该将数组视为内存地址,尤其是将其传递给函数时
你应该这样写:
for(int i = 0; i < n-1; i++)
rhs[i] = ' ';
rhs[n-1] = '\x00'; // null terminator
清理此代码以创建一个完整的最小示例,如下所示:
#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
,这是一个警告。
我正在使用 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
。这应该 return 一个 0
表明字符串是相同的,但我得到了一些其他非零值。
为什么这些字符串不相等?
输入缓冲区的字符串不完全相同,您忽略添加空终止符意味着字符串程序将继续将字符串读入缓冲区,直到找到空终止符,运行 下面的代码向我们展示了这一点:
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 | unknown values ..., could be 0, but until then still part of the array
您应该将数组视为内存地址,尤其是将其传递给函数时
你应该这样写:
for(int i = 0; i < n-1; i++)
rhs[i] = ' ';
rhs[n-1] = '\x00'; // null terminator
清理此代码以创建一个完整的最小示例,如下所示:
#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
,这是一个警告。