Compare Equality of Char[] in C

How to compare a char?

First of, in C single quotes are char literals, and double quotes are string literals.
Thus, 'C' and "C" are not the same thing.

To do string comparisons, use strcmp.

const char* str = "abc";
if (strcmp ("abc", str) == 0) {
printf("strings match\n");
}

To do char comparisons, use the equality operator.

char c = 'a';
if ('a' == c) {
printf("characters match\n");
}

Compare equality of char[] in C

char charTime[] = "TIME"; char buf[] = "SOMETHINGELSE";

C++ and C (remove std:: for C):

bool equal = (std::strcmp(charTime, buf) == 0);

But the true C++ way:

std::string charTime = "TIME", buf = "SOMETHINGELSE";
bool equal = (charTime == buf);

Using == does not work because it tries to compare the addresses of the first character of each array (obviously, they do not equal). It won't compare the content of both arrays.

Comparing characters in C

Because the first sample compares addresses instead of characters.

There is no string type in c and the == operator when applied to an array or a pointer, compares the addresses instead of the contents.

Your function would be correctly written like this

int fq(char *s1,char *s2)
{
int i;
for (i = 0 ; s1[i] ; ++i)
{
if (s1[i] == 'q')
printf("yes");
}

return 1;
}

you can compare s1[i] to 'q'.

Compare two character strings in C

Ok, just to put an end to this. Let's think what string comparing is. First, let's disregard NULL pointers, and assume that both strings are actually valid strings. Then we need no special check.

We will do this by simply comparing them element for element. Whenever we compare two elements at the same index, one of three things can happen:

  1. Both elements are '\0'. The strings are equal. Return true.
  2. The elements differ. Stop comparing and return false.
  3. The elements are equal, but not '\0'. Continue comparing.

Note that the case where "one string has ended" is included in case 2. If only one string has ended, then we will compare '\0' with something else, and thus they will differ.

To make the code very easy to write, you can check if the length is the same first. It makes it a little bit easier, since if they have different length, then they are different, and if they have the same length, you can loop from zero to that length. You could then write it very simple like this:

bool is_equal(char str1[], char str2[])
{
if(strlen(str1) != strlen(str2))
return false;

for(int i=0; i<strlen(str1); i++) {
if(str1[i] != str2[i])
return false;
}

return true;
}

Most important thing here that differs from your code is the realization that as soon as you discover ANY difference, you can return false. The above code is very clear, but a bit inefficient. An obvious optimization is this:

bool is_equal(char str1[], char str2[])
{
int len1 = strlen(str1);
if(len1 != strlen(str2))
return false;

for(int i=0; i<len1; i++) {
if(str1[i] != str2[i])
return false;
}

return true;
}

This removes unnecessary length check in the loop, but it looks messier. Actually, I think I would prefer this:

    int len1 = strlen(str1);
int len2 = strlen(str1);
if(len1 != len2)
return false;

because it looks cleaner. But it's an extra line and an extra variable. But since we can combine the length check with the character check, we can get rid of that completely.

So how can we incorporate the length check in the character check? Well, like this. I want to point out that !str[i] and str[i] != '\0' is completely equivalent in this situation, and it's a very common way to check end of strings.

bool is_equal(char str1[], char str2[])
{
// Infinite loop, but it does not matter. It will end when it should.
for(int i=0; ; i++) {
// If the strings are different, they are different
if(str1[i] != str2[i])
return false;
// At this stage we know that they are equal for all elements
// checked so far, so if both strings ends here, then they are equal.
if(!str1[i] && !str2[i])
return true;
}
}

This is not how I would have implemented it, and I omitted a few details. For instance, I would have used size_t instead of int for the index variable and const for the pointers. It's intended to show how it works in a very simple way. If I implemented it, I would do something like this:

bool is_equal(const char *str1, const char *str2)
{
while(true) {
if(*str1 != *str2)
return false;
if(!*str1 && !*str2)
return true;
str1++;
str2++;
}
}

If you want to work with index variables or pointers is often just a matter of taste. Personally, I think pointers is a bit clearer in this situation. I would also consider adding these lines in the beginning, before the loop:

assert(str1);
assert(str2);

Those will make the program crash if you feed them a NULL pointer.

Demonstration:

https://onlinegdb.com/r1XvzLR3I

c,equality operator on unsigned char and char

From the C11 ISO/IEC 9899:201x standard:

Otherwise, if the operand that has unsigned integer type has
rank greater or equal to the rank of the type of the other
operand, then the operand with signed integer type is
converted to the type of the operand with unsigned integer
type.

The promotion is applied on int y = 0xFFFFFFFF before comparing with unsigned int x = 0xFFFFFFFF. Promoting int y to unsigned int will keep the value 0xFFFFFFFF, which causes x == y.

On the other hand :

If an int can represent all values of the original type (as
restricted by the width, for a bit-field), the value is
converted to an int ; otherwise, it is converted to an unsigned
int . These are called the integer promotions . All other
types are unchanged by the integer promotions. The integer
promotions preserve value including sign. As discussed
earlier, whether a ‘‘plain’’ char is treated as signed is
implementation-defined.

Which means unsigned char a = 0xFF & char b = 0xFF are both converted to signed int before comparison. However converting b will lead to sign extension which means value of b is extended to 0xFFFFFFFF == -1 causing int a = 255 to be greater than int b = -1.

How does c compare character variable against string?

The following code is completely ok in C

No, Not at all.

In your code

  if(ch=="a")

is essentially trying to compare the value of ch with the base address of the string literal "a",. This is meaning-and-use-less.

What you want here, is to use single quotes (') to denote a char literal, like

  if(ch == 'a')

NOTE 1:

To elaborate on the difference between single quotes for char literals and double quotes for string literal s,

For char literal, C11, chapter §6.4.4.4

An integer character constant is a sequence of one or more multibyte characters enclosed in single-quotes, as in 'x'

and, for string literal, chapter §6.4.5

Acharacter string literal is a sequence of zero or more multibyte characters enclosed in
double-quotes, as in "xyz".


NOTE 2:

That said, as a note, the recommend signature of main() is int main(void).

How to Compare 2 Character Arrays

but I read somewhere else that I couldnt do test[i] == test2[i] in C.

That would be really painful to compare character-by-character like that. As you want to compare two character arrays (strings) here, you should use strcmp instead:

if( strcmp(test, test2) == 0)
{
printf("equal");
}

Edit:

  • There is no need to specify the size when you initialise the character arrays. This would be better:

    char test[] = "idrinkcoke";
    char test2[] = "idrinknote";

  • It'd also be better if you use strncmp - which is safer in general (if a character array happens to be NOT NULL-terminated).

    if(strncmp(test, test2, sizeof(test)) == 0)



Related Topics



Leave a reply



Submit