C语言二进制数据和16进制字符串互转

知识点:结构体中的“伸缩型数组成员”(C99新增)

C99新增了一个特性:伸缩型数组成员(flexible array member),利用这项特性声明的结构,其最后一个数组成员具有一些特性。第1个特性是,该数组不会立即存在。第2个特性是,使用这个伸缩型数组成员可以编写合适的代码,就好像它确实存在并具有所需数目的元素一样。声明一个伸缩型数组成员有如下规则:
(1) 伸缩型数组成员必须是结构的最后一个成员;
(2) 结构中必须至少有一个成员;
(3) 伸缩数组的声明类似于普通数组,只是它的方括号中是空的。

data_util.h

#include 
#include 
#include 
#include 

struct byte_array {
	int length;
	//
	// 术语“伸缩型数组成员”(C99新增),必须是结构体的最后一个成员,sizeof 对结构体运算获得的大小不包含该成员,
	// 使用 malloc 分配内存的时候需要额外计算“伸缩型数组”的大小
	//
	uint8_t data[];
};

typedef struct byte_array ByteArray;

//
// 参数是带空格的16进制字符串,如 "11 AA BB"
//
ByteArray* hex_to_data(const char* hex_str);

const char* data_to_hex(const ByteArray* arr);

data_util.c

#include "data_util.h"

ByteArray* hex_to_data(const char* hex_str) {
	printf("%s\n", hex_str);
	int length = (strlen(hex_str) + 1) / 3;

	ByteArray* arr_ptr = malloc(sizeof(ByteArray) + length);
	arr_ptr->length = length;

	int i = 0;
	int byte;
	while (sscanf(hex_str + (i * 3), "%02x", &byte)) {
		//printf("byte%d=%02x\n", i, byte);
		arr_ptr->data[i++] = byte;
		if (hex_str[i * 3] == '\0') {
			break;
		}
	}
	return arr_ptr;
}

const char* data_to_hex(const ByteArray* arr) {
	int length = arr->length;
	char* hex_str = malloc(length * 3);
	char buf[4];
	for (int i = 0; i < length; i++)
	{
		sprintf(buf, "%02X ", arr->data[i]);
		strncpy(hex_str + i * 3, buf, 3);
	}
	hex_str[length * 3 - 1] = '\0';
	return hex_str;
}

main.c

#include 
#include 
#include "data_util.h"

int main(int argc, char* argv[])
{
    char * hex_str = "03 22 AB AB 55 55 55 55";

    ByteArray* arr = hex_to_data(hex_str);
    printf("len=%d\n", arr->length);

    hex_str = data_to_hex(arr);
    printf("data=[%s]\n", hex_str);

    free(arr);
    free(hex_str);

    printf("按 Enter 键退出");
    getchar();
}

你可能感兴趣的:(C语言,c语言,开发语言)