strcmp()如何工作?

Ali*_*pie 19 c string

我一直在寻找答案.我要做出一系列的我自己的字符串函数一样my_strcmp(),my_strcat()等等.

是否strcmp()通过两个字符数组的每个索引工作,如果ASCII值在两个字符串的相同索引处较小,则该字符串按字母顺序更大,因此返回0或1或2?我想我要问的是,它是否使用字符的ASCII值来返回这些结果?

任何帮助将不胜感激.

[修订]

好的,所以我想出了这个...它适用于所有情况,除非第二个字符串大于第一个字符串.

有小费吗?

int my_strcmp(char s1[], char s2[])
{   
    int i = 0;
    while ( s1[i] != '\0' )
    {
        if( s2[i] == '\0' ) { return 1; }
        else if( s1[i] < s2[i] ) { return -1; }
        else if( s1[i] > s2[i] ) { return 1; }
        i++;
    }   
    return 0;
}


int main (int argc, char *argv[])
{
    int result = my_strcmp(argv[1], argv[2]);

    printf("Value: %d \n", result);

    return 0;

}
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 30

伪代码"实现" strcmp将类似于:

define strcmp (s1, s2):
    p1 = address of first character of str1
    p2 = address of first character of str2

    while contents of p1 not equal to null:
        if contents of p2 equal to null: 
            return 1

        if contents of p2 greater than contents of p1:
            return -1

        if contents of p1 greater than contents of p2:
            return 1

        advance p1
        advance p2

    if contents of p2 not equal to null:
        return -1

    return 0
Run Code Online (Sandbox Code Playgroud)

基本上就是这样.依次比较每个字符,根据该字符决定第一个或第二个字符串是否更大.

只有当字符相同时才移动到下一个字符,如果所有字符都相同,则返回零.

请注意,您可能不一定得到1和-1,规格说任何正值或负值都足够了,所以你应该总是用< 0,> 0或者检查返回值== 0.

把它变成真正的C会相对简单:

int myStrCmp (const char *s1, const char *s2) {
    const unsigned char *p1 = (const unsigned char *)s1;
    const unsigned char *p2 = (const unsigned char *)s2;

    while (*p1 != '\0') {
        if (*p2 == '\0') return  1;
        if (*p2 > *p1)   return -1;
        if (*p1 > *p2)   return  1;

        p1++;
        p2++;
    }

    if (*p2 != '\0') return -1;

    return 0;
}
Run Code Online (Sandbox Code Playgroud)

还要记住,字符上下文中的"更大"不一定基于所有字符串函数的简单ASCII排序.

C具有潜在的字符集叫做"语言环境"这一概念指定(除其他事项外)整理或排序,你会发现,例如,人物a,á,à并且ä都被认为是相同的.这将发生在诸如此类的功能上strcoll.

  • 没关系 - "由比较功能memcmp,的strcmp,和STRNCMP返回非零值的符号是由在对象不同是所述第一对字符(既解释为无符号字符)的值之间的差的符号来确定相比".... 很高兴知道 (3认同)
  • 注意:不需要`if (*p2 == '\0') return 1;`。 (2认同)

chr*_*ock 10

这是BSD实现:

int
strcmp(s1, s2)
    register const char *s1, *s2;
{
    while (*s1 == *s2++)
        if (*s1++ == 0)
            return (0);
    return (*(const unsigned char *)s1 - *(const unsigned char *)(s2 - 1));
}
Run Code Online (Sandbox Code Playgroud)

一旦两个字符不匹配,它就会返回这两个字符之间的差异.

  • 值得注意的是,它并不总是*返回两个不同字符之间的差异; 它实际上允许返回任何整数,前提是符号与字节之间的差异相同.对此实现细节的误解(在相关的memcmp函数中)导致了一个真实的[MySQL安全漏洞](http://seclists.org/oss-sec/2012/q2/493). (6认同)
  • 与往常一样,RTFM在使用函数之前.甚至C标准也明确说明了strcmp()的行为:`strcmp函数返回一个大于,等于或小于零的整数,因为s1指向的字符串大于,等于或小于s2指向的字符串.就是这样,没有进一步的保证. (4认同)

nne*_*neo 9

它使用字符的字节值,如果第一个字符串出现在第二个字符串之前(按字节值排序),则返回负值;如果它们相等则返回零;如果第一个字符串出现在第二个字符串之后,则返回正值.由于它以字节为单位运行,因此不能识别编码.

例如:

strcmp("abc", "def") < 0
strcmp("abc", "abcd") < 0 // null character is less than 'd'
strcmp("abc", "ABC") > 0 // 'a' > 'A' in ASCII
strcmp("abc", "abc") == 0
Run Code Online (Sandbox Code Playgroud)

更确切地说,如strcmp Open Group规范中所述:

非零返回值的符号应由所比较的字符串中不同的第一对字节(均被解释为类型无符号字符)的值之间的差的符号确定.

请注意,返回值可能不等于此差异,但它将带有相同的符号.