Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compare Two Character Arrays in C

Tags:

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;
    }
like image 968
Mike John Avatar asked Sep 19 '13 05:09

Mike John


3 Answers

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
}
like image 61
qwwqwwq Avatar answered Sep 27 '22 18:09

qwwqwwq


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;
}
like image 43
Jonathan Leffler Avatar answered Sep 27 '22 18:09

Jonathan Leffler


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;
}
like image 41
Basile Starynkevitch Avatar answered Sep 27 '22 16:09

Basile Starynkevitch