C语言中的异或运算

XOR operation in C

我在 C 语言中的异或运算遇到了几个小时的问题。

我正在尝试对两个 char * 的内容进行异或运算。

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

它们都只包含 01,每个有 5 个插槽。

printftotoreturns00011bobreturns11111.

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

这是我最后要进行异或运算的两个值。

首先我按步骤进行:

1- 将它们中的每一个翻译成一个 int

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

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

如你所见,bob 中的 0 消失了,没问题。

2- 在它们各自相同的位之间使用 XOR 运算符 ^

int result = val_toto ^ val_bob;

问题来了:

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

异或运算的结果应该是

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

真正的问题是,只有当我为 totobob 使用该组合时才会出现问题。 XOR 运算对它们都适用,例如:

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

结果我得到了预期的结果:

101 XOR 1 => 100 //as int

你知道为什么它在上面的组合中工作正常但是当我有 11111 时却没有吗?

谢谢

atoi 和 printf 的 %d 说明符都假设您正在处理十进制格式的数字,而不是二进制。当您进行 XOR 计算时,您假设 11111 和 00011 是二进制的。

当您执行 int result = val_toto ^ val_bob; 时,您使用的是带两位小数的异或运算符,而不是二进制数。 00011 不是 3,而是十进制的 11。要纠正这个错误,请尝试我的代码:

char *str="1100"; // in binary now convert it to decimal so it became 12 
char *endptr=NULL; // to detect any mistake 
int num = strtol(str, &endptr, 2); // strtol meams str to long 2 (binary base ) 
if (endptr!=NULL) { printf("error\n"); exit(1); }
printf("%d\n", num); // will print 12. now you can use it with xor 

问题已经在评论和 中指出。

对于一个解决方案,除非你绝对需要,否则你根本不需要转换为int,你可以在每个单独的字符中执行XOR并将结果保存在新的字符数组,像这样:

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

输出:

11100

如果需要,您始终可以使用 strtol:

安全地转换最终值
char *end;
printf("%ld", strtol(result, &end, 2));

输出:

28

enderrno 上的未决错误检查。

Live sample