使用文件指针,先读取tag及length,再读取value,读文件读两遍,再写入文本文件
文件中有若干程序,把他们全都读取出来,按照length降序,tag降序规则读取出来将所有数据排序以文件形式保存到文本文件中
格式为
No://10进制连续
tag: //16进制 2Byte
len: //10进制
val ://16进制如果length为0则不显示
示例
no:64237
tag:08 6E
len:17
val:5C F0 5F B9 20 1E B1
你应该先读Header,然后算出val数组的大小,再读val的数据
#include <stdio.h>
#include <stdlib.h>
struct Header {
unsigned int no;
unsigned char tag[2];
unsigned int len;
};
struct Program {
struct Header header;
unsigned char *val;
};
struct Node {
struct Program *program;
struct Node *prev;
struct Node *next;
};
unsigned int program_data_size(const struct Header *header) {
unsigned int size = 0;
if (header->len > sizeof(struct Header))
size = header->len - sizeof(struct Header);
return size;
}
struct Program *alloc_program(const struct Header *header) {
struct Program *program = (struct Program *)malloc(sizeof(struct Program));
program->header = *header;
unsigned int size = program_data_size(header);
if (size > 0)
program->val = (unsigned char *)malloc(size);
else
program->val = NULL;
return program;
}
void free_program(struct Program *program) {
free(program->val);
free(program);
}
struct Program *read_program(FILE *file) {
if (feof(file))
return NULL;
struct Header header;
if (fread(&header, sizeof(struct Header), 1, file) != 1) {
perror("failed to read header");
return NULL;
}
struct Program *program = alloc_program(&header);
unsigned int size = program_data_size(&header);
if (fread(program->val, sizeof(unsigned char), size, file) != size) {
perror("corrupted file");
free_program(program);
return NULL;
}
return program;
}
void add_to_list(struct Node **list, struct Program *program) {
if (*list == NULL) {
struct Node *p = (struct Node *)malloc(sizeof(struct Node));
p->program = program;
p->prev = NULL;
p->next = NULL;
*list = p;
return;
}
struct Node *prev = (*list)->prev;
struct Node *p = *list;
while (p) {
if (p->program->header.len < program->header.len ||
(p->program->header.len == program->header.len &&
p->program->header.tag < program->header.tag))
break;
prev = p;
p = p->next;
}
struct Node *q = (struct Node *)malloc(sizeof(struct Node));
q->program = program;
q->next = p;
q->prev = prev;
if (prev)
prev->next = q;
if (p)
p->prev = q;
}
void destroy_list(struct Node *list) {
struct Node *p = list;
while (p) {
free_program(p->program);
struct Node *q = p;
p = p->next;
free(q);
}
}
void print_program_to_file(const struct Program *program, FILE *file) {
fprintf(file, "no:%d\n", program->header.no);
fprintf(file, "tag:%02X %02X\n", program->header.tag[0],
program->header.tag[1]);
fprintf(file, "len:%d\n", program->header.len);
fprintf(file, "value:");
unsigned int size = program_data_size(&program->header);
for (unsigned int i = 0; i < size; i++) {
fprintf(file, "%02X", program->val[i]);
if (i < size - 1)
fprintf(file, " ");
}
fprintf(file, "\n");
}
void print_list_to_file(const struct Node *list, FILE *file) {
const struct Node *p = list;
while (p) {
print_program_to_file(p->program, file);
p = p->next;
}
}
int main() {
FILE *in_file = fopen("input.bin", "rb");
if (!in_file) {
perror("failed to open input.bin");
return 1;
}
struct Node *list = NULL;
struct Program *program = NULL;
while ((program = read_program(in_file)) != NULL)
add_to_list(&list, program);
fclose(in_file);
FILE *out_file = fopen("output.txt", "w");
if (!out_file) {
perror("failed to open output.txt");
return 2;
}
print_list_to_file(list, out_file);
fclose(out_file);
destroy_list(list);
return 0;
}
对TLV的操作,可以参考之前写的这个demo程序
TLV 格式及编解码示例_来灵的博客-CSDN博客_tlv编码
有没有大佬能不用双向链表,用正常的指针操作读取写入文件啊,就先读tag 和length再读value,最后写入
先读Tag,根据Tag,调用不同的解释器处理Value,完成后,指针根据Length的长度移动,重复前面的步骤。