【问题标题】:Putting Hex into a byte array将十六进制放入字节数组
【发布时间】:2016-12-06 19:52:40
【问题描述】:

我正在尝试将十六进制值放入Byte[],尝试实现 78,66,1E,B5,4F,E7,67,63

   #define BYTE   unsigned char
   int num = 1;

   long long hex[]
   {
     0x78661EB54FE76763,
   };

 int main()
 {

        for (int c = 0; c < num; c++)
        {
            printf("%llx\n", hex[c]);

            unsigned int number = hex[c];
            unsigned int ef = number & 0xff;
            unsigned int cd = (number >> 8) & 0xff;
            unsigned int ab = (number >> 16) & 0xff;

            printf("%x", number & 0xff);

            BYTE data2[8]{
                ef, cd, ab
            };

        }
}

更新:

基本上我有一个包含 30 个奇数十六进制值的数组。我正在尝试遍历名为 hex[] 的数组,然后将每个十六进制值分成 2 个,即 78、66、1E、B5、4F、E7、67、63,然后将每个数组添加到 BYTE 类型的数组中将十六进制值保存为 8 对,因此 data[0] 的值为 78,data[8] 的值为 63,因此我可以将 BYTE 类型的数组传递给另一种方法以进行进一步的工作

【问题讨论】:

  • 这不会按原样编译。因为long long hex[] 是一个带有初始值设定项的声明,所以该语句在第一个花括号之前需要一个= 符号:{,并且在结束花括号之后是一个C 语句终止符:;}。并且0x78661EB54FE76763后面的逗号应该去掉。
  • 现在将为您编译,更新
  • 你一直在说“基本上我有一个包含 30 个奇数十六进制值的数组。”。你是什​​么意思,你的样本显示一长一长,价值一大。你真正的起始数据是什么,在问题中显示出来

标签: c arrays hex


【解决方案1】:

这是您想要的解决方案:

#include <stdio.h>
typedef unsigned char BYTE;
int main()
{
    int i,j;
    long long hex=0x78661EB54FE76763;
    BYTE val[8];

    for(j=0,i=7; i>=0; i--,j++){
        val[j]= (hex>>(i*8))&0xff;
    }       

    printf("Hexadecimal bytes are:\n");
    for(j=0;j<8;j++){
        printf("%02X ",val[j]);
    }

    return 0;

}   

输出是:

Hexadecimal bytes are:
78 66 1E B5 4F E7 67 63

【讨论】:

  • 我认为 OP 想把一个大数字分解成小数字。您正在使用少量数字进行初始化。
  • 基本上我有一个包含 30 个奇数十六进制值的数组。我正在尝试遍历名为 hex[] 的数组,然后将每个十六进制值分成 2 个,即 78、66、1E、B5、4F、E7、67、63,然后将每个数组添加到 BYTE 类型的数组中将十六进制值保存为 8 对,因此 data[0] 的值为 78
  • 如果值为long long hex=0x78661EB54FE76763 | 0x8000000000000000;,符号位的右移会导致“值是实现定义的”C11 §6.5.7 5 。最好使用unsigned long long hex
【解决方案2】:

假设BYTE是一个类型

BYTE data2[] = {ef, cd, ab, '\0'};

使用null 终止符以允许使用"%s"printf() 进行打印。

当然,您可以添加其余字节。

【讨论】:

  • 是的 BYTE 是一种类型,我在上面更新了,抱歉,如果我解释这是一种令人困惑的方式。我只是不知道如何简单地将它们成对地添加到两个
【解决方案3】:

这是一项非常简单的任务,只需您提供的初始化值即可完成。

long long hex[] = { 0x78661EB54FE76763 };

接下来,您需要一个指向十六进制数组的 char 指针

unsigned char* pByte = (unsigned char*)hex; // Point to the first element in hex array

然后创建一个 8 字节的缓冲区并用 memset 清除它:

unsigned char byteArray[8];
memset(byteArray, 0, sizeof(byteArray));

您现在需要做的就是取消引用您的 char 指针并将值放入您的 8 字节缓冲区。

// Loop through the hex array and assign the current byte
// the byte pointer is pointing to then increment the byte pointer
// to look at the next value.
// This for loop is for a system that is little endian (i.e. win32)
for (int i = 7; i >= 0; i--)
{
  byteArray[i] = *pByte;
  pByte++;  
} 

注意:因为我是用 Visual Studio 2015 运行的,所以一切都是小端的。这就是为什么第一个 for 循环是这样写的。

以下是我编写和测试的完整程序清单,以证明这一点:

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

int main(void)
{
  long long hex[] = { 0x78661EB54FE76763 };    // Value of an element
  unsigned char* pByte = (unsigned char*)hex;  // Assign a char pointer to point to the first element in hex array
  unsigned char byteArray[8];                  // This is the byte buffer that will be populated from the hex array
  memset(byteArray, 0, sizeof(byteArray));     // Clear out the memory of byte array before filling in the indices

  // Loop through the hex array and assign the current byte
  // the byte pointer is pointing to then increment the byte pointer
  // to look at the next value.
  // This for loop is for a system that is little endian (i.e. win32)
  for (int i = 7; i >= 0; i--)
  {
    byteArray[i] = *pByte;  // Dereference the pointer and assign value to buffer
    pByte++;                // Point to the next byte
  }

  // Print the byte array
  for(int i = 0; i < 8; i++)
  {
    printf("The value of element %i is: %X\n", i, byteArray[i]);
  }

  printf("Press any key to continue...");   // Hold the console window open
  getchar();
  return 0;
}

【讨论】:

  • 当你在下一个循环中覆盖整个数组时,为什么要“用 memset 清除它”
  • 我喜欢将所有内容初始化为已定义的状态以避免未定义的行为。
  • 使用 = { 0 }; 代替 memset 可以降低由于 memset 出错而导致 UB 的风险
  • 我知道这种语法,但不能保证在所有平台上都能保证,特别是如果你有一个联合作为结构的一部分。哪里 memset 是有保证的,它得到了很好的优化,而且它有点冗长。两种方式我都做过,但我更喜欢使用 memset。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-08-08
  • 2017-06-17
  • 2018-02-28
  • 2011-05-07
  • 1970-01-01
  • 1970-01-01
  • 2013-02-18
相关资源
最近更新 更多