简体   繁体   English

在 C 中创建我自己的 strcmp () 函数

[英]Creating my own strcmp () function in C

I was assigned by my teacher to write my own strcmp() function in C. I did create my own version of said function, and I was hoping to get some feedback.我被老师指派​​用 C 编写我自己的strcmp()函数。我确实创建了我自己的所述函数版本,我希望得到一些反馈。

int CompareTwoStrings ( char *StringOne, char *StringTwo ) {
    // Evaluates if both strings have the same length.
    if  ( strlen ( StringOne ) != strlen ( StringTwo ) ) {
        // Given that the strings have an unequal length, it compares between both
        // lengths.
        if  ( strlen ( StringOne ) < strlen ( StringTwo ) ) {
            return ( StringOneIsLesser );
        }
        if  ( strlen ( StringOne ) > strlen ( StringTwo ) ) {
            return ( StringOneIsGreater );
        }
    }
    int i;
    // Since both strings are equal in length...
    for ( i = 0; i < strlen ( StringOne ); i++ ) {
        // It goes comparing letter per letter.
        if  ( StringOne [ i ] != StringTwo [ i ] ) {
            if  ( StringOne [ i ] < StringTwo [ i ] ) {
                return ( StringOneIsLesser );
            }
            if  ( StringOne [ i ] > StringTwo [ i ] ) {
                return ( StringOneIsGreater );
            }
        }
    }
    // If it ever reaches this part, it means they are equal.
    return ( StringsAreEqual );
}

StringOneIsLesser, StringOneIsGreater, StringsAreEqual are defined as const int with the respective values: -1, +1, 0. StringOneIsLesser、StringOneIsGreater、StringsAreEqual 被定义为具有各自值的 const int:-1、+1、0。

Thing is, I'm not exactly sure if, for example, my StringOne has a lesser length than my StringTwo, that automatically means StringTwo is greater, because I don't know how strcmp() is particularly implemented.问题是,我不确定,例如,我的 StringOne 的长度是否比我的 StringTwo 短,这自动意味着 StringTwo 更大,因为我不知道strcmp()是如何特别实现的。 I need some of your feedback for that.我需要你的一些反馈。

So much for such a simple task.如此简单的任务就这么多了。 I believe something simple as this would do:我相信一些简单的事情会这样做:

int my_strcmp(const char *a, const char *b)
{
    while (*a && *a == *b) { ++a; ++b; }
    return (int)(unsigned char)(*a) - (int)(unsigned char)(*b);
}

strcmp compares alphabetically: so "aaa" < "b" even though "b" is shorter. strcmp按字母顺序比较:所以"aaa" < "b"即使“b”更短。

Because of this, you can skip the length check and just do the letter by letter comparison.因此,您可以跳过长度检查,只进行逐个字母的比较。 If you get to a NULL character while both strings are equal so far, then the shorter one is the lesser one.如果到目前为止两个字符串都相等时遇到一个 NULL 字符,那么较短的字符是较小的字符。

Also: make StringsAreEqual == 0 , not 1 for compatibility with standard sorting functions.另外:为了与标准排序函数兼容,使StringsAreEqual == 0而不是1

    int mystrncmp(const char * str1, const char * str2, unsigned int n)
     {
      while (*str1 == *str2) {
          if (*str1 == '\0' || *str2 == '\0')
             break;

          str1++;
          str2++;
       }


   if (*str1 == '\0' && *str2 == '\0')
      return 0;
   else
      return -1;
}

strcmp() is fairly easy to code. strcmp()相当容易编码。 The usual mis-codings issues include:通常的错误编码问题包括:

Parameter type参数类型

strcmp(s1,s2) uses const char * types, not char * . strcmp(s1,s2)使用const char *类型,而不是char * This allows the function to be called with pointers to const data.这允许使用指向const数据的指针调用const It conveys to the user the function's non-altering of data.它向用户传达了该功能对数据的不变性。 It can help with optimization.它可以帮助优化。

Sign-less compare无符号比较

All str...() function perform as if char was unsigned char , even if char is signed.所有str...()函数都像charunsigned char一样执行,即使char是有符号的。 This readily affects the result when strings differ and a character outside the range [1...CHAR_MAX] is found.当字符串不同并且发现范围[1...CHAR_MAX]之外的字符时,这很容易影响结果。

Range范围

On select implementations, the range of unsigned char minus unsigned char is outside the int range.在选择实现中, unsigned char减去unsigned char的范围在int范围之外。 Using 2 compares (a>b) - (ab) avoids any problem rather than ab;使用 2 个比较(a>b) - (ab)避免了任何问题,而不是ab; . . Further: many compilers recognized that idiom and emit good code.进一步:许多编译器认识到这个习惯用法并发出好的代码。

int my_strcmp(const char *s1, const char *s2) {
  // All compares done as if `char` was `unsigned char`
  const unsigned char *us1 = (const unsigned char *) s1;
  const unsigned char *us2 = (const unsigned char *) s2;

  // As long as the data is the same and '\0' not found, iterate
  while (*us1 == *us2 && *us1 != '\0') {
    us1++;
    us2++;
  }

  // Use compares to avoid any mathematical overflow 
  // (possible when `unsigned char` and `unsigned` have the same range).
  return (*us1 > *us2) - (*us1 < *us2);
}

Dinosaur computers恐龙电脑

Machines that use a signed char and non-2's complement, the following can be wrong or a trap with *s1 != '\\0' .使用有符号char和非 2 的补码的机器,以下内容可能是错误的或带有*s1 != '\\0'的陷阱。 Such machines could have a negative 0 - which does not indicate the end of a string, yet quits the loop.这样的机器可能有一个负 0 - 这并不表示字符串的结尾,但会退出循环。 Using unsigned char * pointers solves that.使用unsigned char *指针可以解决这个问题。

int my_strcmp(const char *s1, const char *s2) {
  while (*s1 == *s2 && *s1 != '\0') { // Error!
    s1++;
    s2++;
  }

Try this also for your better understanding:也试试这个,以便您更好地理解:

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

int main(void)
{
    char string1[20], string2[20];
    int i=0,len=0, count=0;
    puts("enter the stirng one to compare");
    fgets(string1, sizeof(string1), stdin);
    len = strlen(string1);
    if(string1[len-1]=='\n')
    string1[len-1]='\0';

    puts("enter the stirng two to compare");
    fgets(string2, sizeof(string2), stdin);
    len = strlen(string2);
    if(string2[len-1]=='\n')
    string2[len-1]='\0';
    if(strlen(string1)==strlen(string2))
    {
    for(i=0;string1[i]!='\0', string2[i]!='\0', i<strlen(string1);i++)
    {
        count=string1[i]-string2[i];
        count+=count;
    }
        if(count==0)
            printf("strings are equal");
        else if(count<0)
            printf("string1 is less than string2");
        else if(count>0)
            printf("string2 is less than string1");
    }

    if(strlen(string1)<strlen(string2))
    {
    for(i=0;string1[i]!='\0', i<strlen(string1);i++)
    {
        count=string1[i]-string2[i];
        count+=count;
    }
        if(count==0)
            printf("strings are equal");
        else if(count<0)
            printf("string1 is less than string2");
        else if(count>0)
            printf("string2 is less than string1");
    }

    if(strlen(string1)>strlen(string2))
    {
    for(i=0;string2[i]!='\0', i<strlen(string2);i++)
    {
        count=string1[i]-string2[i];
        count+=count;
    }
        if(count==0)
            printf("strings are equal");
        else if(count<0)
            printf("string1 is less than string2");
        else if(count>0)
            printf("string2 is less than string1");
    }


    return 0;
}
bool str_cmp(char* str1,char* str2)
{
    if (str1 == nullptr || str2 == nullptr)
        return false;


    const int size1 = str_len_v(str1);
    const int size2 = str_len_v(str2);

    if (size1 != size2)
        return false;

    for(int i=0;str1[i] !='\0' && str2[i] !='\0';i++)
    {
        if (str1[i] != str2[i])
            return false;
    }

    return true;
}

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

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