将32位字符串分成4个8位十六进制数(使用C语言)

6

社区,我在C语言方面经验较少,目前正在学习过程中。

我正在开发一个小项目,涉及将一个32个字符的字符串分成四个包含8个字符的子串。这个32个字符的字符串应该类似于一个32位指令。这些“32位”被分成四个“8位”的字符串,我想要将其打印出来作为十六进制数。下面是我目前所得到的代码。我正在使用和我代码中其他部分相同的数据类型。我打算将unsigned char t变量输入到一个替换盒程序中,该程序将从S-Box查找表中给出t字符的等效值。

以下代码看起来对我来说应该可以正常工作。

unsigned char inst[] = "10101010101010101111111100111101";
unsigned char in[8];
for (int i = 0; i < 33; i++){
        if (i%8 == 0 && i != 0) {
                unsigned char t = (unsigned char) strtol(in, NULL, 2);
                printf("%x \n", t);
    }

    in[i%8] = inst[i];
    printf("%c ", in[i%8]);
}

但输出结果看起来像这样:
1 0 1 0 1 0 1 0 3d
1 0 1 0 1 0 1 0 3d
1 1 1 1 1 1 1 1 3d
0 0 1 1 1 1 0 1 3d

我看到 in[i%8] = inst[i]; 这一行正确地从 inst[] 中读取了 chars,但是……
if (i%8 == 0 && i != 0) {
                unsigned char t = (unsigned char) strtol(in, NULL, 2);
                printf("%x \n", t);
    }

条件语句打印错误的十六进制代码。 输出应该类似于以下内容:

1 0 1 0 1 0 1 0 aa
1 0 1 0 1 0 1 0 aa
1 1 1 1 1 1 1 1 ff
0 0 1 1 1 1 0 1 3d

非常感谢您的帮助。


3
至少存在一个问题:将unsigned char in[8]更改为unsigned char in[9],并需要在使用strtol之前在八个字符的字符串末尾添加空字符终止符。请参阅C语言教材中处理字符串的章节。 - Jabberwocky
1
Strtol仅在第8位转换时被调用,因此从功能上讲,它是在赋值之后被调用的。这个链接可以正常工作:https://onlinegdb.com/HktzG8THN - farbiondriven
1
@Lundin - 当 i == 8 时,首次调用 strtol - in 在迭代 i == 0i == 7 期间被填充。 - user200783
@Jabberwocky - 同意,问题在于in没有以NUL结尾,因此strtol会读取数组末尾之后的内容。 - user200783
@farbiondriven - 你的示例代码是否需要将 in[8] 初始化为 NUL? - user200783
谢谢大家的好建议。代码已经运行成功,我现在明白我需要使用NUL来终止字符串中的in[]。干杯! - Ameer Shalabi
2个回答

4

当前代码存在的问题:

  • "4个8字符字符串"需要用char in[4][8+1];而不是char in[8]。你需要留出空间来进行空终止。
  • 32位意味着从0到31迭代,而不是从0到32。
  • 没有必要逐字节复制。这会变慢并使一切变得过于复杂。

这似乎是要求:

  • 将原始字符串分成4个子字符串。
  • 将每个子字符串转换为整数。
  • 以十六进制显示结果

在这种情况下,您只需在输入字符串上循环4次即可:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

int main (void)
{
  const char* inst = "10101010101010101111111100111101";
  char in [4][8+1];

  puts("Bin      Hex");
  for(size_t i=0; i<4; i++)
  {
    memcpy(in[i], &inst[i*8], 8);
    in[i][8] = '\0';
    unsigned long val = strtoul(in[i], NULL, 2);    
    printf("%.8s %.2lX\n", in[i], val);
  }
}

输出:

Bin      Hex
10101010 AA
10101010 AA
11111111 FF
00111101 3D

3
问题在于你的in没有以NUL结尾。
因此,将in传递给strol会导致未定义的行为发生。 请按以下方式操作。
    unsigned char in[9]; //+1 to hold the NUL char.

     ....
    if (i%8 == 0 && i != 0) {
                in[8] = '\0'; //NUL terminate the string.
                unsigned char t = (unsigned char) strtol(in, NULL, 2);
                printf("%x \n", t);
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接