23

我一直在寻找答案。我将制作一系列我自己的字符串函数,如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;

}
4

9 回答 9

35

的伪代码“实现”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

基本上就是这样。依次比较每个字符,然后根据该字符决定第一个字符串还是第二个字符串更大。

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

请注意,您可能不一定会得到 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;
}

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

C 有一个称为“语言环境”的概念,它指定(除其他外)排序规则或基础字符集的顺序,例如,您可能会发现字符、 和aá被认为是相同的。这将发生在像.àästrcoll

于 2012-08-27T04:53:14.810 回答
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));
}

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

于 2012-08-27T04:48:54.663 回答
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

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

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

请注意,返回值可能不等于这个差值,但它带有相同的符号。

于 2012-08-27T04:44:35.137 回答
4

这是我的版本,为小型微控制器应用程序编写,符合 MISRA-C。这段代码的主要目的是编写可读的代码,而不是大多数编译器库中的单行 goo。

int8_t strcmp (const uint8_t* s1, const uint8_t* s2)
{
  while ( (*s1 != '\0') && (*s1 == *s2) )
  {
    s1++; 
    s2++;
  }

  return (int8_t)( (int16_t)*s1 - (int16_t)*s2 );
}

注意:代码假定为 16 位int类型。

于 2012-08-27T06:39:35.640 回答
4

这来自大师们自己(K&R,第 2 版,第 106 页):

// strcmp: return < 0 if s < t, 0 if s == t, > 0 if s > t
int strcmp(char *s, char *t) 
{
    int i;

    for (i = 0; s[i] == t[i]; i++)
        if (s[i] == '\0')
            return 0;
    return s[i] - t[i];
}
于 2015-12-04T08:15:48.290 回答
2

这段代码是等价的,更短,更易读:

int8_t strcmp (const uint8_t* s1, const uint8_t* s2)
{
    while( (*s1!='\0') && (*s1==*s2) ){
        s1++; 
        s2++;
    }

    return (int8_t)*s1 - (int8_t)*s2;
}

我们只需要测试 s1 的结尾,因为如果我们在 s1 的结尾之前到达 s2 的结尾,循环将终止(因为 *s2 != *s1)。

如果我们只使用 7 位(纯 ASCII)字符,则返回表达式在每种情况下都会计算正确的值。 由于存在整数溢出的风险,需要仔细考虑为 8 位字符生成正确的代码。

于 2014-05-12T03:18:27.960 回答
1

我在网上找到了这个。

http://www.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);
}
于 2015-09-15T11:50:03.733 回答
-1

这就是我实现strcmp 的方式: 它的工作原理如下:它比较两个字符串的第一个字母,如果相同,则继续到下一个字母。如果不是,则返回相应的值。它非常简单易懂:#include

//function declaration:
int strcmp(char string1[], char string2[]);

int main()
{
    char string1[]=" The San Antonio spurs";
    char string2[]=" will be champins again!";
    //calling the function- strcmp
    printf("\n number returned by the strcmp function: %d", strcmp(string1, string2));
    getch();
    return(0);
}

/**This function calculates the dictionary value of the string and compares it to another string.
it returns a number bigger than 0 if the first string is bigger than the second
it returns a number smaller than 0 if the second string is bigger than the first
input: string1, string2
output: value- can be 1, 0 or -1 according to the case*/
int strcmp(char string1[], char string2[])
{
    int i=0;
    int value=2;    //this initialization value could be any number but the numbers that can be      returned by the function
    while(value==2)
    {
        if (string1[i]>string2[i])
        {
            value=1;
        }
        else if (string1[i]<string2[i])
        {
            value=-1;
        }
        else
        {
            i++;
        }
    }
    return(value);
}
于 2015-01-09T12:05:31.630 回答
-2

只是这样:

int strcmp(char *str1, char *str2){
    while( (*str1 == *str2) && (*str1 != 0) ){
        ++*str1;
        ++*str2;
    }
    return (*str1-*str2);
}

如果你想要更快,你可以在类型前添加“register”,像这样:register char

然后,像这样:

int strcmp(register char *str1, register char *str2){
    while( (*str1 == *str2) && (*str1 != 0) ){
        ++*str1;
        ++*str2;
    }
    return (*str1-*str2);
}

这样,如果可能,使用 ALU 的寄存器。

于 2016-07-03T13:14:26.790 回答