【问题标题】:strcmp() thinks that strings arent equal.. but are they? [duplicate]strcmp() 认为字符串不相等.. 但它们是吗? [复制]
【发布时间】:2012-08-19 23:02:45
【问题描述】:

由于未知原因,运行我的 C 程序的结果出乎意料。我认为它必须是某种初学者的错误,但我真的不知道它在哪里。

#include <stdio.h>
#include <string.h>
int main()
{
char string1[50];
char string2[50];
int compare;

puts("Enter two strings: ");
fgets(string1, strlen(string1)+1, stdin);
fgets(string2, strlen(string2)+1, stdin);

compare=strcmp(string1, string2); /* usage of extra variable makes the code more readable but wastes more memory */

printf("%d: ",compare);

if (compare<0) puts("First string is lesser");
else if (compare>0) puts ("First string is bigger");
     else puts("Strings are equal");


return 0;
  }

在测试中:

Enter two strings: 
heheisntthisalongstring
heheisntthisalongstring
1: First string is bigger


------------------
(program exited with code: 0)
Press return to continue

这些字符串不应该相等吗?

【问题讨论】:

  • 您的 fgets() 调用中断,您传递的长度不正确。未初始化的 char[] 具有随机长度。练习使用调试器查看此类问题。
  • 非常感谢。我今天将学习使用调试器。
  • 只是一个额外的问题。如果我使用 strlen() 将数组初始化为 0 后,程序将结束,我没有机会输入字符串。将 strlen() 更改为 sizeof 可以解决问题,但为什么会出现上述情况?
  • @hardpenguin fgets(s, num, stream) 读取字符,直到读取 (num-1) 个字符或到达换行符或文件结尾,以先到者为准。当使用全 0 初始化字符串时,strlen 返回 0,而 fgets 没有要读取的字符。

标签: c compare fgets strcmp


【解决方案1】:
fgets(string1, strlen(string1)+1, stdin);
fgets(string2, strlen(string2)+1, stdin);

这些都是错误的。 string1string2 未初始化,strlen 只计算字节数,直到达到 \0。在这种情况下,strlen 可以返回任何(随机非负数)数字。

在这里使用sizeof,而不是strlen

【讨论】:

  • 非常感谢!我会记住这一点的。
【解决方案2】:

这里

 char string1[50]; 
 char string2[50]; 

您没有初始化它们,因此您对strlen 的初始调用是不可靠的,因为它们正在寻找在数组开始后找到的第一个空字符。这可能在任何地方,调用的结果可能会或可能不会真实反映大小 - 您根本不能依赖结果。

【讨论】:

    【解决方案3】:

    string1 不是 memset 为 0,所以strlen(string1) 值不会给出预期值(50)。 strlen 将对字符进行计数,直到达到\0。所以它也可能导致崩溃(一种未定义的行为)。

    string1string2 更好的 memset,如下所示。

    char string1[50] = {0}; 
    char string2[50] = {0};
    

    并且还使用sizeof 运算符来获取值50

    fgets(string1, sizeof(string1), stdin); 
    fgets(string2, sizeof(string2), stdin);
    

    要不然直接去scanf

    scanf("%s", string1);
    scanf("%s", string2);
    

    【讨论】:

    • 数组上的 Memset 零在调用 strlen 时不会导致“预期值为 50”
    • 如果我们传递 memsetted string1,strlen(string1) 将给出零。这就是我建议使用 sizeof 而不是 strlen 的。最好在使用之前将所有缓冲区都设置为 0。
    • memsetting 所有缓冲区会以非常糟糕的方式影响性能。
    • @raja ashok 我同意只是您的回答表明 memsetting 为零将给出 50 的值。
    • @hardpenguin,sizeof() 是基于编译器的。编译器计算出该点的大小并将其转换为常量。 strlen() 计算从指针所在位置到下一个空值的字符串长度。这就是为什么 strlen 在这种情况下不起作用的原因(因为您将所有内容都设置为零)。
    【解决方案4】:

    这里看看this-strlen

    虽然您使用的代码不好,但您仍然可以通过使用strncmp 为第三个参数提供公共字符串变量的strlen 来获得预期的答案。只是为了好玩。 始终初始化您的变量,否则它们会导致您的应用程序崩溃。可以看例子here- strncmp

    【讨论】:

    • 没有初始化和使用具有相同 strlen 变量的 strncmp 仍然会使您的应用程序崩溃。只是说清楚,我不认可这段代码:-)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-26
    相关资源
    最近更新 更多