为什么在C语言中比较字符串不起作用?

5
我有以下程序。
main()
{

    char name[4] = "sara";
    char vname[4] = "sara";

    if(strcmp(name, vname) == 0)
    {
        printf("\nOK");
    }
    else
    {
        printf("\nError");
    }

}

这个程序总是输出 "Error" ... 问题出在哪里,帮我看看

但是,如果我改变 char vname[] = "sara",那么它就会打印出 "OK" ... 为什么??


这与问题并不特别相关,但是C++不允许char name[4] = "sara";;如果您指定了大小,则必须有足够的空间来容纳尾随的'\0' - Keith Thompson
4个回答

21

你硬编码了数组的大小,使它们对于字符串来说太短(它们没有为 null 终止符留下额外的字符)。结果,当 strcmp 进行比较时,会超出字符串的结尾,从而产生基本上不可预测的结果。幸运的是,你没有得到 seg fault。


12
如果他真的遇到了段错误,他会更幸运。 - Keith Thompson
你能告诉我在C语言中分配字符串或创建字符串的最佳方法是什么吗? - srisar
正如其他人建议的那样,您可以在数组声明中省略显式维度值,编译器将根据其初始化程序调整它们的大小(例如,char name [] =“sara”)。 - Jollymorphic

10

如果我偏离了主题,请原谅,因为我很久没用C语言了!

main()
{
    char name[] = "sara";
    char vname[] = "sara";

    if(strcmp(name, vname) == 0)
    {
        printf("\nOK");
    }
    else
    {
        printf("\nError");
    }
}

您已经为 char 数组指定了固定的长度,但在 C 语言中,字符串以空字符结尾,因此 "sara" 的实际长度为5而不是4。

9
因为namevname并不包含字符串。通过为它们的每个指定大小为4,并使用四个字符的字符串作为初始化器,您已经告诉编译器仅存储这4个字符,而没有标记字符串结尾的'\0'空字符。
行为是未定义的;你很(不)幸运,它没有崩溃。
删除4(或将其更改为5):
char name[] = "sara";
char vname[] = "sara";

编辑: 这是您程序的修改版本,修复了其他几个问题(请参阅注释)。 除省略namevname声明中的4之外,大多数更改与您的问题无直接关系。

#include <stdio.h>  /* needed for printf */
#include <string.h> /* needed for strcmp */

int main(void) /* correct declaration of "main" */
{

    char name[] = "sara";   /* omit 4 */
    char vname[] = "sara";  /* omit 4 */

    if (strcmp(name, vname) == 0)
    {
        printf("OK\n");     /* \n is at the *end* of the line */
    }
    else
    {
        printf("Error\n");  /* as above */
    }

    return 0; /* not absolutely required, but good style */
}

1

这是因为您没有为字符串分配足够的空间(4个字节可以存储“sara”的字符,但不能存储字符串末尾的nul字符。

strcmp遍历字符串,直到达到nul字符或字符串之间的差异,如果两个字符串都达到了nul,则它们相等。由于您没有为nul字符分配足够大的数组,因此您最终会得到两个不相等的字符串。实际上,在大多数系统中,您可能会得到类似“sarasara”的名称和仅为“sara”的vname,因为vname紧随name之后,有很大的机会在内存中存储并覆盖names nul字符。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接