如果两个相似的字符串长度不同,strcmp会返回什么?

21

我了解如果您在strcmp(这是一个C问题)中有“cat”(string1)和“dog”(string2),那么strcmp的返回值将小于0(因为“cat”在字典顺序上小于“dog”)。

但是,如果发生以下情况,我不确定strcmp会发生什么:

string1: 'dog'
string2: 'dog2'.
strcmp函数返回什么?小于零,零或者大于零?在这个语境下,我试图编写一个比较字符串的比较器函数并且想要考虑到以相同字符开头的字符串。一个字符串可能会有一个扩展名(例如,在上面的例子中,“dog2”中的“2”)。

编辑:这不是重复的问题。这个问题与其被认为类似的问题询问返回类型代表什么有所不同 - 我是在说当字符串在某一点上相同但一个停止而另一个继续时会发生什么。

4
为什么不直接尝试一下呢? - Some programmer dude
1
可能是c中strcmp()返回值的重复 - MicroVirus
4
因为我发现在C语言中,事情并不总是一致的。类型的大小就是一个很好的例子。 - Daniel Soutar
2
C语言非常一致,如果您遇到不一致的行为,那么很抱歉,可能是您误解了某些内容或者使用/做错了某些事情。或者您是指像sizeof(int)这样依赖于实现的内容?它仍然是一致的,因为它按照正式的C标准规定工作。字符串及其行为在各个平台和实现之间是一致的,但我会承认字符编码可能会有所不同,但是字符串和字符和字符串函数的行为仍然是一致的。 - Some programmer dude
5个回答

14

它返回不同八位字节之间的差异。在您的例子中,'\0' < '2',因此返回了某些负数。


2
哦,所以基本上是在比较空字符?那总是小于任何其他字符对吧? - Daniel Soutar

7

根据C标准,它被定义为第一对不匹配字符之间的差异,但实现方式却各有不同。唯一的共同点是当字符串相等时返回值为零,然后针对 str1<str2str1>str2 分别返回 <0 或 >0

memcmpstrcmpstrncmp 的比较函数的非零返回值的符号由待比较对象中第一对不同的字符(均解释为无符号字符)的值的差异所决定。

但一些实现会返回经典的值,如 0, 1 和 -1。例如苹果的实现 (http://opensource.apple.com//source/Libc/Libc-262/ppc/gen/strcmp.c):

int
strcmp(const char *s1, const char *s2)
{
    for ( ; *s1 == *s2; s1++, s2++)
    if (*s1 == '\0')
        return 0;
    return ((*(unsigned char *)s1 < *(unsigned char *)s2) ? -1 : +1);
}

编辑: 在 Android 的 Donut-release 引导库中 (https://android.googlesource.com/platform/bootable/bootloader/legacy/+/donut-release/libc/strcmp.c),如果字符串相等,则该函数返回 0,对于其他两种情况则返回 1,并仅使用逻辑运算:

int strcmp(const char *a, const char *b)
{
    while(*a && *b) {
        if(*a++ != *b++) return 1;
    }
    if(*a || *b) return 1;
    return 0;
}

2

C11引用

C11 N1570标准草案

我认为以下引用保证了"dog" < "dog2":

7.23.4比较函数 1 比较函数memcmp、strcmp和strncmp返回的非零值的符号由对象中第一对不同的字符(均解释为unsigned char)的值之差的符号决定。

因此,字符被解释为数字,'\0'保证为0

然后:

7.23.4.2 strcmp函数 2 strcmp函数将s1指向的字符串与s2指向的字符串进行比较。

显然比较字符串,且:

7.1.1术语定义 1 字符串是以包括第一个空字符在内的连续字符序列结尾的。

表明空字符是字符串的一部分。

最后:

5.2.1字符集 2 [...]基本执行字符集中存在一个所有位都设置为0的字节,称为空字符;它用于终止字符字符串。

因此,'\0'等于零。

由于解释为unsigned char,且所有字符都不同,因此零是可能的最小数字。


1

来自strcmp的man手册:

如果发现s1(或其前n个字节)分别小于、匹配或大于s2,则strcmp()和strncmp()函数返回一个整数小于、等于或大于零。

这通常类似于@hroptatyr所描述的实现。


所以,只是为了澄清一下,Thomas - 在较短的字符串末尾的空字符被比较,因此较小的字符串“小于”较大的字符串? - Daniel Soutar
1
@DanielSoutar 是的。 - totoro

0

如果你想比较两个字符串的初始len个字符,使用strncmp而不是strcmp:

#include <string.h>
size_t len = 3;
int res = strncmp("dog", "dog2", len);

在这种情况下,res将为0。


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