简体   繁体   English

C中的strcmp返回1而不是0

[英]strcmp in C returns 1 instead of 0

I wrote the following code in C. 我用C语言编写了以下代码。

#include <stdio.h>
#include <string.h>
int main(void) {
    char str1[4] = "abcd";
    char str2[4] = "abcd";
    printf("%d\n",strcmp(str1,str2));

    return 0;
}

I expected the return value to be 0 (as I am taught that strcmp function returns 0 for equal strings). 我期望返回值为0(因为有人告诉我strcmp函数对于相等的字符串返回0)。 But it prints 1! 但它打印1!

Success  time: 0 memory: 2248 signal:0
1

Is it a bug? 是虫子吗? Or am I missing out on something? 还是我错过了什么?

Because your arrays are not long enough. 因为您的数组不够长。 Your are not taking into account the zero terminator of your strings. 您没有考虑字符串的零终止符。 You need 5 chars for your string, four for the string itself plus one for the zero terminator. 您的字符串需要5个字符,字符串本身需要4个字符,零终止符需要1个字符。

Write: 写:

char str1[5] = "abcd";
char str2[5] = "abcd";

BTW I wonder why your compiler does not issue a warning or does it ? 顺便说一句,我想知道为什么您的编译器不发出警告还是发出警告?

One of your strings looks like this in memory: 'a' 'b' 'c' 'd' '\\0'. 您的一个字符串在内存中看起来像这样:'a''b''c''d''\\ 0'。 That is, like every string it is terminated by '\\0' which is a character just like 'a' or 'b'. 也就是说,像每个字符串一样,它以“ \\ 0”结尾,该字符就像“ a”或“ b”一样。 Therefore you need room for five chars in order to store the string "abcd" and must declare it by char str1[5]. 因此,为了存储字符串“ abcd”,您需要五个字符的空间,并且必须通过char str1 [5]对其进行声明。

Either you give correct size for your arrays, either you let the compiler to do everything for you 为数组提供正确的大小,或者让编译器为您做所有事情

 char str1[] = "abcd";
 char str2[] = "abcd";

in this case, compiler will give enough space for your strings. 在这种情况下,编译器将为您的字符串提供足够的空间。

(Courtesy Pascal Cuoq) (由Pascal Cuoq提供)

The C99 standard §6.7.8.¶14 says C99标准§6.7.8.¶14说

An array of character type may be initialized by a character string literal, optionally enclosed in braces. 字符类型的数组可以由字符串文字初始化,并可选地用大括号括起来。 Successive characters of the character string literal (including the terminating null character if there is room or if the array is of unknown size) initialize the elements of the array. 字符串文字的连续字符(如果有空间或数组大小未知,则包括终止空字符)将初始化数组的元素。

Since strings are terminated by the null byte '\\0' , the actual number of characters in the string literal "abcd" is 5 . 由于字符串以空字节'\\0'终止,因此字符串文字"abcd"的实际字符数为5 The size of the arrays str1 and str2 is 4 . 数组str1str2的大小为4 Therefore, they cannot hold the null byte and are, in fact, not strings. 因此,它们不能保存空字节,并且实际上不是字符串。 The below statements are equivalent. 以下陈述是等效的。

char str1[4] = "abcd";
char str1[4] = {"abcd"}
char str1[4] = {'a', 'b', 'c', 'd'};

Passing str1 and str2 to strcmp invokes undefined behaviour because they are not strings. str1str2传递给strcmp调用未定义的行为,因为它们不是字符串。 strcmp will overrun the buffer pointed to by str1 and str2 since it cannot find the terminating null byte. strcmp无法找到终止的空字节,因此它将溢出str1str2 str1的缓冲区。 This is undefined behaviour and may result in program crash due to segfault. 这是未定义的行为,并可能由于段错误而导致程序崩溃。

A string is a character array terminated by the null byte '\\0' . 字符串是一个以空字节'\\0'结尾的字符数组。 Therefore, the length of the string literal "abcd" is 5 and not 4 . 因此,字符串文字"abcd"的长度为5而不是4 Note that the standard library function strlen does not count the null byte so in this case, strlen("abcd") returns 4 . 请注意,标准库函数strlen不计算空字节,因此在这种情况下, strlen("abcd")返回4

When you initialize an array with a string literal, it is a good practice to leave your array size blank which is automatically determined to be large enough to store all the characters in the string literal it is initialized with. 使用字符串文字初始化数组时,最好将数组大小留为空白,该大小会自动确定为足以将所有字符存储在使用其初始化的字符串文字中。

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

int main(void) {
    char str1[] = "abcd";
    char str2[] = "abcd";
    printf("%d\n", strcmp(str1, str2));  // prints 0

    return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM