tugouzhishen 2022-09-22 19:35 采纳率: 88.5%
浏览 103
已结题

C语言读取TLV数据写入文本文件

问题遇到的现象和发生背景
用代码块功能插入代码,请勿粘贴截图
我的解答思路和尝试过的方法

使用文件指针,先读取tag及length,再读取value,读文件读两遍,再写入文本文件

img

我想要达到的结果

文件中有若干程序,把他们全都读取出来,按照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

  • 写回答

4条回答 默认 最新

  • _GX_ 2022-09-22 20:36
    关注
    获得2.70元问题酬金

    你应该先读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;
    }
    
    评论 编辑记录

报告相同问题?

问题事件

  • 系统已结题 9月30日
  • 赞助了问题酬金10元 9月22日
  • 创建了问题 9月22日

悬赏问题

  • ¥15 微软硬件驱动认证账号申请
  • ¥15 有人知道怎么在R语言里下载Git上的miceco这个包吗
  • ¥15 GPT写作提示指令词
  • ¥20 如何在cst中建立这种螺旋扇叶结构
  • ¥20 根据动态演化博弈支付矩阵完成复制动态方程求解和演化相图分析等
  • ¥20 关于DAC输出1.000V对分辨率和精度的要求
  • ¥15 华为超融合部署环境下RedHat虚拟机分区扩容问题
  • ¥15 哪位能做百度地图导航触点播报?
  • ¥15 请问GPT语言模型怎么训练?
  • ¥15 已知平面坐标系(非直角坐标系)内三个点的坐标,反求两坐标轴的夹角