Mike John
Mike John

Reputation: 818

Compare Two Character Arrays in C

I have a string struct.

struct string
{
   char *c;
   int length;
   int maxLength;
}

I want to check if two strings are equal.

So I want to run a for loop.

for(int i = 0; i < length; i++)
   if(s1[i] != s2[i]) // This code is more C# than C.

s1 and s2 are both string structs.

How do I do this if(s1[i] != s2[i]) ?

EDIT: I just did this, is it over kill?

    for(i = 0; i < length; i++)
    if((*s1).c[i] != (*s2).c[i])
    {
        printf("Failed");
        return 0;
    }

Upvotes: 6

Views: 63659

Answers (5)

Jonathan Leffler
Jonathan Leffler

Reputation: 755010

I'm assuming you want to write the comparison code yourself, rather than using built-ins such as strcmp() — which might be performance boosted by being written in, or generated as, optimized assembler code. The are_equal() function will return 1 (true) if the strings are equal and 0 (false) otherwise.

Sub-optimal solution

static inline int min(int a, int b) { return (a < b) ? a : b; }

int are_equal(const struct string *s1, const struct string *s2)
{
    int len = min(s1->length, s2->length);
    int i;
    for (i = 0; i < len; i++)
    {
        if (s1->c[i] != s2->c[i])
            return 0;  // They are different
    }
    return(s1->c[i] == s2->c[i]);
}

The inline function assumes a C99 compiler; you can replace it with an appropriate macro if you're stuck using C89.

More nearly optimal solution

int are_equal(const struct string *s1, const struct string *s2)
{
    if (s1->length != s2->length)
        return 0; // They must be different
    for (int i = 0; i < s1->length; i++)
    {
        if (s1->c[i] != s2->c[i])
            return 0;  // They are different
    }
    return 1;  // They must be the same
}

Both versions of the code assume that the strings in s1->c and s2->c are null-terminated and that s1->length == strlen(s1->c) and s2->length == strlen(s2->c).

With C99, it would also be possible to use _Bool as the return type, or <stdbool.h> and bool (as the return type) and true and false as the return values.

Alternative solution using strcmp()

Note that if you simply use strcmp(), you will get 0 if the strings are equal and a non-zero value if the strings are unequal. So, you might also write the function like this to return true if the strings are equal and false otherwise:

int are_equal(const struct string *s1, const struct string *s2)
{
    return strcmp(s1->c, s2->c) == 0;
}

Upvotes: 6

qwwqwwq
qwwqwwq

Reputation: 7329

Assuming you can use C-strings with \0 termination I would do that and use strcmp:

if (strcmp(s1.c, s2.c)) {
    // action if strings are not equal
}

Upvotes: 10

Your if statement is incomplete (perhaps lacking setting a flag then a break or a return), and you don't use the struct so perhaps

struct string {
  char *c;
  int length;
  int maxLength;
};

bool same_string (struct string *s1, struct string* s2) {
  int ln1 = s1->length;
  if (ln1 != s2->length) return false;
  for (int i=0; i<ln1; i++)
    if (s1->c[i] != s2[ci]) return false;
  return true;
}

But you really want strncmp i.e. just

bool same_string (struct string *s1, struct string* s2) {
  if (s1->length != s2->length) return false;
  return strncmp(s1->c, s2->c, s1->length)==0;
}

Upvotes: 3

Freddie
Freddie

Reputation: 891

You don't really need to know the length of the strings to compare them. You can use the string compare tools in the standard library strncmp preferably over strcmp, or you can write your own similar to this:

int strcmp(char *s1, char *s2)
{
  int i;
  for (i = 0; s1[i] == s2[i]; i++)
    if (s1[i] == '\0')
      return 0;
  return s1[i] - s2[i];
}

Upvotes: 0

P0W
P0W

Reputation: 47844

You need to compare each member

int compare(struct string s1, struct string s2){

return (strcmp(s1.c,s2.c) == 0) && 
       (s1.maxLength ==s2.maxLength) &&
       (s1.length ==s2.length) ;
}

for(int i = 0; i < length; i++)
   if(!compare(s1,s2)) { 
  }

Upvotes: 1

Related Questions