Создание моей собственной функции strcmp () в C

Мой учитель назначил меня написать strcmp() Функция в C. Я создал свою собственную версию указанной функции, и я надеялся получить обратную связь.

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 определяются как const int с соответствующими значениями: -1, +1, 0.

Дело в том, что я не совсем уверен, если, например, мой StringOne имеет меньшую длину, чем мой StringTwo, это автоматически означает, что StringTwo больше, потому что я не знаю, как strcmp() особенно реализовано. Мне нужны ваши отзывы для этого.

4 ответа

Так много для такой простой задачи. Я считаю, что-то простое, как это будет делать:

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

strcmp сравнивает по алфавиту: так "aaa" < "b" хотя "б" короче.

Из-за этого вы можете пропустить проверку длины и просто выполнить построчное сравнение. Если вы получите символ NULL, пока обе строки равны, то чем короче, тем меньше.

Также: сделать 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() довольно легко кодировать. Обычные ошибки неверного кодирования включают в себя:

Тип параметра

strcmp(s1,s2) использования const char * типы, а не char *, Это позволяет вызывать функцию с указателями на const данные. Он передает пользователю функцию неизменения данных. Это может помочь с оптимизацией.

Сравнение без знака

Все str...() функция выполняет как будто char было unsigned char, даже если char подписано Это легко влияет на результат, когда строки различаются и символ находится за пределами диапазона [1...CHAR_MAX] найден.

Спектр

На некоторых реализациях диапазон unsigned char минус unsigned char находится за пределами int спектр. Используя 2 сравнения (a>b) - (a-b) избегает любой проблемы, а не a-b;, Далее: многие компиляторы распознают эту идиому и испускают хороший код.

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);
}
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;
}

Попробуйте это также для вашего лучшего понимания:

#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;
}
Другие вопросы по тегам