gpt4 book ai didi

c - 如何获取和存储二进制值进行运算?

转载 作者:行者123 更新时间:2023-11-30 14:37:29 26 4
gpt4 key购买 nike

我正在尝试将字符数组转换为二进制。我现在花了一个小时仔细阅读 SO 帖子,但很少有人完全满足我的需要,而且没有一个对我有用。

void formatCallSign(unsigned char *callsign) {
unsigned char new[7];
printf("original is %s",callsign);
for (int j = 0; j < 6; j++) {
printf("Hex of this is %x", callsign[j]); // this correctly prints out the original hex value
char binary[9];
binary[0] = ( (callsign[j] & (1 << 7)) ? '1' : '0' );
binary[1] = ( (callsign[j] & (1 << 6)) ? '1' : '0' );
binary[2] = ( (callsign[j] & (1 << 5)) ? '1' : '0' );
binary[3] = ( (callsign[j] & (1 << 4)) ? '1' : '0' );
binary[4] = ( (callsign[j] & (1 << 3)) ? '1' : '0' );
binary[5] = ( (callsign[j] & (1 << 2)) ? '1' : '0' );
binary[6] = ( (callsign[j] & (1 << 1)) ? '1' : '0' );
binary[7] = ( (callsign[j] & (1 << 0)) ? '1' : '0' );
printf("Binary of %c is: %x\r\n", callsign[j], binary); // print hex representation of character
}
}

本质上,该函数的输入是一个 7 个字符的字符串(字符数组)。我还使用了嵌套的 for 循环,但是编译器生成了毫无意义的无限循环错误,所以我像这样重写了它。

然后我需要获取该字符的二进制表示形式,并进行左移 1(并非总是如此,但 95% 的情况下,我可以稍后添加逻辑)。移位后,我需要十六进制值。

事实证明,获取二进制值是难以捉摸的。在之前的项目中,我从来无法正确执行此操作,只能获取十六进制值。在这种情况下,我还可以在第二个 printf 语句中获取 hax 值,但我无法对十六进制值进行按位移位,因为我需要移位各个位。

但是,当我运行该程序时,它总是显示Binary of [char] is: 9A。始终为 9A,这不是十六进制表示。我传入的字符串中的任何字符。

我的想法是使用sprintf并传入数组并使用%x来获取它的十六进制表示。现在,它打印到控制台,但我实际上会将其存储在新数组中,该数组现在在此代码段中未使用。有可能以某种方式做到这一点吗?获取二进制文件的代码似乎不起作用(基于 this answer 的第二部分)。

(澄清一下,此代码段中的第二个和第三个 printf 语句应该输出相同的内容。只有第二个有效。这样绘制的原因这样我就可以进行按位运算,然后使用 sprintf 将其放回连贯的单个值并从中获取十六进制。)

许多问题都涉及这个主题,但很少有帮助,因为我对将二进制文件打印到控制台不感兴趣。相反,我需要将二进制文件存储在变量中,对其进行按位运算,然后获取最终二进制文件的十六进制表示形式。现在,我可以成功获得原始字符的十六进制表示,但这没有帮助。

我唯一的其他想法是 manually define the binary values of every hex number然后将其用作“查找表”,但这似乎效率低下。

要测试这一点,所需的所有其他内容就是 main 中的以下内容:

unsigned char dest[8]   = "CQ     ";
formatCallSign(&dest);

最佳答案

这里有两个问题。我将首先介绍简单、肤浅的内容。您的代码几乎正确地将字符转换为其二进制表示形式。它将该表示形式创建为字符串。 (这可能不是您想要的;稍后会详细介绍。)但是它会尝试使用 printf 的 %x 打印字符串。格式。现在,%x用于打印数字,而不是字符串,并且由于 C 处理数组和指针的方式有时令人惊讶,如果您有一个数组 char binary[9]然后您尝试使用 %x 打印它,你得到的是数组的地址,而不是数组的内容。我认为这就是为什么你每次都得到相同的值。

您还忘记对构造的 binary 进行 null 终止字符串。

这是您的 formatCallSign 的更正版本功能。 (我同时清理了一些其他东西。)

void formatCallSign(unsigned char *callsign) {
printf("original is %s\n",callsign);
for (int j = 0; j < strlen(callsign); j++) {
printf("Hex of %c is %x\n", callsign[j], callsign[j]);
char binary[9];
binary[0] = ( (callsign[j] & (1 << 7)) ? '1' : '0' );
binary[1] = ( (callsign[j] & (1 << 6)) ? '1' : '0' );
binary[2] = ( (callsign[j] & (1 << 5)) ? '1' : '0' );
binary[3] = ( (callsign[j] & (1 << 4)) ? '1' : '0' );
binary[4] = ( (callsign[j] & (1 << 3)) ? '1' : '0' );
binary[5] = ( (callsign[j] & (1 << 2)) ? '1' : '0' );
binary[6] = ( (callsign[j] & (1 << 1)) ? '1' : '0' );
binary[7] = ( (callsign[j] & (1 << 0)) ? '1' : '0' );
binary[8] = '\0';
printf("Binary of %c is: %s\r\n", callsign[j], binary);
}
}

有了这个功能,当我调用formatCallSign("CQ")时,它打印

original is CQ
Hex of C is 43
Binary of C is: 01000011
Hex of Q is 51
Binary of Q is: 01010001

没关系,这是有道理的,这些是 C 的正确二进制表示形式。和Q以 ASCII 表示。

但它带来的麻烦也远远超过了它的值(value)——而且事实上它毫无用处。您说您的最终目标是移动这些字符中的位,但将所有内容转换为字符串数组 binary将使这个问题变得更加困难。 (我们甚至还没有解决将二进制字符串转换回真正的 8 位字符的问题。)

正如您可能知道的,您在 C 程序中操作的几乎所有内容(字符、整数、 float 、字符串)在内部深处都已经是二进制形式了。例如,字符 C内部已表示为 01000011。它只是看起来像字符 C如果你使用%c打印出来,它看起来只是十六进制数 43如果你使用%x打印出来。在内心深处,它仍然是 01000011,当您以其他形式打印出来时,它并没有改变。

由于字符在内部已经表示为二进制数字,因此如果您想将字符的二进制表示形式左移 1,您可以通过简单、直接的 << 应用程序来实现。运算符,无需事先显式转换为二进制。这是encryptCallSign函数可以实现我认为您想要的功能:

void encryptCallSign(unsigned char *callsign) {
for(int j = 0; j < strlen(callsign); j++) {
unsigned char newchar = callsign[j] << 1;
printf("%X -> %X\n", callsign[j], newchar);
callsign[j] = newchar;
}
}

我尝试通过一个小测试来调用它 main功能如下:

main()
{
char callSign[] = "CQ";
formatCallSign(callSign);
printf("encrypting...\n");
encryptCallSign(callSign);
printf("encrypted:\n");
formatCallSign(callSign);
}

这是我得到的输出:

original is CQ
Hex of C is 43
Binary of C is: 01000011
Hex of Q is 51
Binary of Q is: 01010001
encrypting...
43 -> 86
51 -> A2
encrypted:
original is ¢
Hex of is 86
Binary of is: 10000110
Hex of ¢ is a2
Binary of ¢ is: 10100010

这看起来有点有趣,因为值为 A2 的字符是¢符号(无论如何,在 ISO-8601-1“Latin1”中),以及值为 86 的字符没有打印表示。

虽然很简单,encryptCallSign我展示的函数大约是所需长度的两倍。如果它没有打印出它的工作,我们可以将其简化为

void encryptCallSign(unsigned char *callsign) {
for(int j = 0; j < strlen(callsign); j++)
callsign[j] = callsign[j] << 1;
}

(您也可以使用 C 的“op ="快捷方式 callsign[j] <<= 1 。)

这里还有一些其他问题 - 例如,我的编译器正确地提示 char * 存在一些可疑的混合。和unsigned char *类型正在发生——但这应该会给你指明正确的方向。

关于c - 如何获取和存储二进制值进行运算?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57296082/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com