简体   繁体   English

使用 C 语言读取和存储大型 hex 文件数据

[英]Reading and Storing large hex file data using C language

I need to read a large Intel Hex file and based on data type, need to store the data in a string/character array to use later on.我需要读取一个大型 Intel Hex 文件并根据数据类型,需要将数据存储在字符串/字符数组中以供以后使用。 Below is the code, I am using chunk to read line from hex file, using data_type to check the data type in read line, sub to store parsed data from line and finaldata to keep adding data as I read.下面是代码,我使用块从十六进制文件中读取行,使用 data_type 检查读取行中的数据类型,使用 sub 存储行中的解析数据,使用 finaldata 在读取时继续添加数据。 However the problem is size, the max character array size is 65535 (correct me if I am wrong) but my data is around 80,000 bytes (120K characters).但是问题是大小,最大字符数组大小是 65535(如果我错了,请纠正我)但我的数据大约是 80,000 字节(120K 个字符)。 How can I tackle this (using C language)?我该如何解决这个问题(使用 C 语言)? or it be better if I switch to C++ or C#?或者如果我切换到 C++ 或 C# 会更好? Thanks in advance for any help/insight you can provide.提前感谢您提供的任何帮助/见解。

Edit: Hex data from file looks like below: :020000 04 0200F1:10C000 00 814202D8BFF32F8F10BD441C42E8004366 I need to read this data line by line and based from data type (shown in bold, 04 in first line, 00 in second), if it's 00, parse the data from the next byte (byte after data type) and read until end except last byte (which is checksum).编辑:文件中的十六进制数据如下所示::020000 04 0200F1:10C000 00 814202D8BFF32F8F10BD441C42E8004366 我需要逐行读取此数据并根据数据类型(以粗体显示,第一行为 04,第二行为 00),如果它是 00 ,从下一个字节(数据类型后的字节)解析数据并读取直到最后一个字节(即校验和)除外。 Then move to next line, if the data type is 00, parse the data and add it to previously read data (string concatenation), so the variable needs to store a big amount of final data (this is I where I am struggling, how to store that large amount of data in a single variable)?然后移动到下一行,如果数据类型为00,则解析数据并将其添加到之前读取的数据中(字符串连接),所以变量需要存储大量的最终数据(这是我苦苦挣扎的地方,如何将大量数据存储在单个变量中)?

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

int main(void)
{
    FILE *fp;
    fp = fopen(*filename, "rb");
    if(fp == NULL) {
        perror("Unable to open file!");
        exit(1);
    }

    char chunk[128];
    char sub[128];

    char finaldata[65535];
    finaldata[0] = '\0';
    // Store the chunks of text into a line buffer
    size_t len = sizeof(chunk);

    while(fgets(chunk, sizeof(chunk), fp) != NULL) {
        //fputs(chunk, stdout);
        int a=0;

        if((chunk[7] == '0') && (chunk[8] == '0')) {
            size_t length = strlen(chunk);

            while (a < (length-13)) {
                sub[a]=chunk[9+a];
                a++;

            }
        }
        strcat(finaldata, sub);
        fputs(finaldata, stdout);
        memset(sub,0,sizeof(sub));
         printf("\n\n");

    }

    fclose(fp);

    printf("\n\nMax line size: %zd\n", len);

    return 0;
}

You say:你说:

read until end except last byte (which is checksum)读取直到结束,除了最后一个字节(这是校验和)

but if I apply on :10C00000814202D8BFF32F8F10BD441C42E8004366 your code但如果我申请:10C00000814202D8BFF32F8F10BD441C42E8004366你的代码

    int a=0;

    if((chunk[7] == '0') && (chunk[8] == '0')) {
        size_t length = strlen(chunk);

        while (a < (length-13)) {
            sub[a]=chunk[9+a];
            a++;
        }
    }

sub values 814202D8BFF32F8F10BD441C42E8004 so you remove 366 at the end of the line rather than only 66814202D8BFF32F8F10BD441C42E8004所以你在行尾删除366而不仅仅是66


From your remark从你的言论

when defining char array using malloc() function, what size should I put in there since I don't know the exact size?使用 malloc() function 定义 char 数组时,由于我不知道确切的大小,我应该放什么大小?

If you want to collapse all the sub strings in one string, one way is to start by an array of size 1 for the null terminating char then to increase it line per line using malloc .如果要折叠一个字符串中的所有子字符串,一种方法是从一个大小为 1 的数组开始,用于 null 终止字符,然后使用malloc每行增加它。 For instance:例如:

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

int main(int argc, char ** argv)
{
  if (argc != 2) {
    fprintf(stderr, "Usage: %s <file>\n", *argv);
    exit(1);
  }

  FILE *fp = fopen(argv[1], "rb");

  if (fp == NULL) {
    perror("Unable to open file!");
    exit(1);
  }

  size_t sz = 0; /* without counting the char for \n */
  char * finaldata = malloc(1);
  char chunk[128];

  while (fscanf(fp, " %127s", chunk) == 1) {
    if((chunk[7] == '0') && (chunk[8] == '0')) {
      if (strlen(chunk) != 43) {
        fprintf(stderr, "unexpected line '%s'\n", chunk);
        exit(1);
      }

      chunk[41] = 0; /* remove two last chars */

      char * s = realloc(finaldata, sz + 32 +1); /* + block + \n */

      if (s == NULL) {
        fputs("not enough memory", stderr);
        free(finaldata); /* for valgrind etc */
        exit(1);
      }

      finaldata = s;
      strcpy(finaldata + sz, chunk + 9);
      sz += 32;
    }
  }

  fclose(fp);
  finaldata[sz] = '\0';

  /* debug */
  puts(finaldata);

  free(finaldata); /* for valgrind etc */

  return 0;
}

I use fscanf to bypass possible spaces including newline before and after the part to manage.我使用fscanf绕过可能的空格,包括要管理的部分前后的换行符。 In the format " %127s" notice the space before '%', and 127 which is 128 minus 1 to let place for the null terminating char." %127s"格式中,请注意“%”之前的空格和 127,即 128 减 1,以便放置 null 终止字符。

Compilation and execution:编译和执行:

pi@raspberrypi:/tmp $ gcc -Wall c.c
pi@raspberrypi:/tmp $ cat f
:020000040200F1
:10C00000814202D8BFF32F8F10BD441C42E8004366
:020000040200F1
:10C00000123456789abcdef0123456789abcdef012
pi@raspberrypi:/tmp $ ./a.out f
814202D8BFF32F8F10BD441C42E80043123456789abcdef0123456789abcdef0
pi@raspberrypi:/tmp $ 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM