Vanguard
Vanguard

Reputation: 139

A proper way of comparing unequal char arrays in c

Is there a proper way of comparing two char-arrays if they aren't equal by length? How to check which character isn't equal?

strcmp seems to give me only bigger or lesser number, not the position of unequal character.

For example, strings:

/home/jjjj/ and
/home/jjjj/kkkk/asdasd

Should return 12

Upvotes: 2

Views: 1470

Answers (4)

Lundin
Lundin

Reputation: 213306

Maybe something like this:

const char* strcmp_plusplus (const char* str1, const char* str2)
{
  const char* result = NULL; // return NULL if equal

  while(*str1 != '\0')
  {
    if(*str1 != *str2)
    {
      result = str1;  // point at where in str1 they are different
      break;
    }

    str1++;
    str2++;
  }

  return result;
}

Note that we won't have to check if str2 is \0, because the C standard allows us to read one element beyond an array without invoking undefined behavior. If str2 ends before str1, the function will return a pointer to str1's null termination.

Upvotes: 1

alk
alk

Reputation: 70883

Using strlen() and strstr() you can achieves this in a two-step approach:

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


char str1[] = "this is a long string";
char str2[] = "long";

{
  char * ss = NULL;
  char * sg = NULL;
  size_t size1 = strlen(str1)
  size_t size2 = strlen(str2);
  size_t size_ss = 0;

  /* step 1: determine which of the two strings tobe compared it the smaller/greater one. */
  if (size1 > size2)
  {
    size_ss = size2;
    ss = str2;
    sg = str1;
  }
  else
  {
    size_ss = size1;
    ss = str1;
    sg = str2;
  }

  /* step 2: find out where the smaller string is located in the greater one, if ever... */
  {
    char * p = strstr(sg, ss);

    if (p)
    {
      printf("'%s' is the same as '%s' from character %zu to character %zu.\n", 
        sg, ss, p - sg, p - sg + size_ss);
    }
    else
    {
      /* printf("The strings are 100%% differently!\n"); */ /* changed as per Jonathan's comment. */
      printf("'%s' does not appear in '%s'.\n", ss, sg);
    }
  }
}

This solution does not take into account that the shorter string could appear more than once in the longer string. It always notifies about the first occurrence.

Upvotes: 4

wildplasser
wildplasser

Reputation: 44220

This function attempts to do it all at once. Since a function can only return one value, one of the resulting values (the difference) has to be passed back to the caller via a pointer to it.

#include <stdio.h>

size_t lead_cmp( const char * one, const char * two, int *result);
size_t lead_cmp( const char * one, const char * two, int *result)
{
    size_t pos;

    for(pos=0; one[pos] && two[pos]; pos++) {
        if (one[pos] != two[pos]) break;
    }

    *result = one[pos] - two[pos];
    return pos;
}

int main(int argc, char **argv)
{
    size_t len;
    int diff;

    len = lead_cmp (argv[1], argv[2], &diff );
    printf( "Pos=%zu, Rc=%d\n", len, diff);

    return 0;
}

Result:

$ ./a.out /home/jjjj/ /home/jjjj/kkkk/
Pos=11, Rc=-107
$

The found position is 11, not 12, since C uses 0-based indexing.

It returns the number of matching characters: the length of the common prefix.

Upvotes: 0

Jonathan Leffler
Jonathan Leffler

Reputation: 753475

There isn't a standard C function that returns the first point of discrepancy between two strings.

It wouldn't be hard to create one; take a version of strcmp() from a text book and modify it so that returns the offset of the strings at the point where the result is 'interesting'. If the strings are equal, that will be the offset of the null terminator ('\0'); otherwise, it will be the offset where the two strings are different.

Upvotes: 3

Related Questions