Search code examples
ccharxor

XOR operation in C


I've been facing a problem for a few hours with my XOR operation in C.

I'm trying to XOR the content of two char * between each other.

char* toto = malloc(sizeof(char)*5);
char* bob = malloc(sizeof(char)*5);

They both contain only 0 and 1 with 5 slots each.

The printf for toto returns 00011 and bob returns 11111.

printf("%s", toto) => 11111
printf("%s", bob)  => 00011

These are the two values that I'm trying to XOR in the end.

First I proceed by steps :

1- Translate each of them into an int value

int val_toto = atoi(toto); 
int val_bob = atoi(bob);

// printf("%d", val_toto) => 11111
// printf("%d", val_bob)  => 11

As you can see the 0 in bob disapeared, no problem.

2- Use the XOR operator ^ between their respective same bits

int result = val_toto ^ val_bob;

And here comes the problem :

printf("%d", result) => 11116

The result of the XOR operation should be

  11111
^ 00011  // the 0 are taken care of even if not showed in printf
-------
  11100  // but I get 1116 ???

The real deal is that the problem occurs only when I use that combination for toto and bob. The XOR operations works fine for all of them, example :

toto => 00101   // as char*
bob => 000001
//then I use atoi() with each of them
toto => 101     // as int
bob => 1  

And as a result I get what's expect :

101 XOR 1 => 100 //as int

Do you have any idea why it works fine in the combination above for instance but never when I have a 11111 ?

Thank you


Solution

  • The problem was already pointed out in the comments and in David Grayson answer.

    For a solution, unless you absolutely need to, you wouldn't need to convert to int at all, you can perform the XOR in each individual character and save the result in a new char array, something like this:

    char toto[] = "11111";
    char bobo[] = "00011";
    
    size_t len = strlen(toto);  // use strlen only if toto is null terminated
                                // otherwise use the size of the array
    char result[len]; 
                               
    for(size_t i = 0; i < len; i++) // same here
    {
        result[i] = (toto[i] ^ bobo[i]) + '0';
    }
    
    printf("%s", result); // again if the arrays are null terminated,
                          // otherwise print it in a for cycle
                          // using the array size
    

    Output:

    11100
    

    If need be you can always safely convert the final value by using strtol:

    char *end;
    printf("%ld", strtol(result, &end, 2));
    

    Output:

    28
    

    Pending error checks on end and errno.

    Live sample