Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/67.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用C语言读取和存储大型十六进制文件数据_C_Arrays_Char_C Strings - Fatal编程技术网

用C语言读取和存储大型十六进制文件数据

用C语言读取和存储大型十六进制文件数据,c,arrays,char,c-strings,C,Arrays,Char,C Strings,我需要读取一个大的Intel十六进制文件,根据数据类型,需要将数据存储在字符串/字符数组中,以便以后使用。下面是代码,我使用chunk从十六进制文件中读取行,使用data_type检查读取行中的数据类型,sub存储从行中解析的数据,finaldata在读取时不断添加数据。但是问题是大小,最大字符数组大小是65535(如果我错了请纠正我),但我的数据大约是80000字节(120K个字符)。 如何解决这个问题(使用C语言)?还是我切换到C++或C语言更好? 提前感谢您提供的任何帮助/见解 编辑:文件

我需要读取一个大的Intel十六进制文件,根据数据类型,需要将数据存储在字符串/字符数组中,以便以后使用。下面是代码,我使用chunk从十六进制文件中读取行,使用data_type检查读取行中的数据类型,sub存储从行中解析的数据,finaldata在读取时不断添加数据。但是问题是大小,最大字符数组大小是65535(如果我错了请纠正我),但我的数据大约是80000字节(120K个字符)。 如何解决这个问题(使用C语言)?还是我切换到C++或C语言更好? 提前感谢您提供的任何帮助/见解

编辑:文件中的十六进制数据如下所示: :020000040200F1 :10C00000814202D8BF32F8F10BD441C42E8004366 我需要逐行读取此数据,并基于数据类型(粗体显示,第一行显示04,第二行显示00),如果是00,则从下一个字节(数据类型后的字节)解析数据,直到最后一个字节(即校验和)之外的数据结束。然后移到下一行,如果数据类型为00,则解析数据并将其添加到以前读取的数据(字符串串联),因此变量需要存储大量最终数据(这就是我正在努力的地方,如何在单个变量中存储大量数据)

#包括
#包括
#包括
内部主(空)
{
文件*fp;
fp=fopen(*文件名,“rb”);
如果(fp==NULL){
perror(“无法打开文件!”);
出口(1);
}
字符块[128];
char-sub[128];
char finaldata[65535];
最终数据[0]='\0';
//将文本块存储到行缓冲区中
size\u t len=sizeof(块);
while(fgets(chunk,sizeof(chunk),fp)!=NULL){
//FPUT(块、标准输出);
int a=0;
如果((块[7]=='0')&&(块[8]=='0')){
大小\u t长度=strlen(块);
而(a<(长度-13)){
子[a]=块[9+a];
a++;
}
}
strcat(最终数据,分包);
FPUT(最终数据、标准数据);
memset(sub,0,sizeof(sub));
printf(“\n\n”);
}
fclose(fp);
printf(“\n\n最大行大小:%zd\n”,len);
返回0;
}
你说:

除最后一个字节(即校验和)外,一直读取到结束

但如果我申请的是
:10C00000814202D8BF32F8F10BD441C42E8004366
你的代码

    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++;
        }
    }
我使用
fscanf
绕过可能的空格,包括要管理的零件前后的换行符。在格式
“%127s”
中,请注意“%”之前的空格,以及127,它是128减去1,以便为空终止字符留出空间

汇编和执行:

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 $ 

最大字符数组大小为65535(如果我错了,请纠正我)-是的,您错了。当你需要一个大数组时,不要将它放在堆栈中,使用动态内存分配(<代码> MaloC ),是的,C++将为你提供可以很好地欣赏的“容器类”。您可以使用“straight C”来完成这项工作——使用bruno的建议来使用
malloc
,但只需“从货架上抓取一个合适的容器类”就可以了,并且知道它会按照广告中的方式工作。“懒惰是一种美德,”我现在使用C++,在每一种情况下我都使用C(而且我经常使用其他解释性语言)BTW——“80000字节(120 K字符)”——听起来很奇怪。您的“字符”是否小于字节?
strcmp(“00”,数据类型)
具有未定义的行为,数组长度仅为2,您设置了它的2个元素,但没有空终止字符。执行
strcat(最终数据,sub)在你的循环中是免费的,至少每次保存结束位置/ptr,为什么要使用中间数组子?感谢详细的回答,我现在得到了动态内存分配。但是我有一个问题,关于“finaldata=s”;为什么它只增加了“finaldata”字符串的大小,为什么它没有将“s”(空字符串)的内容复制到“finaldata”中?关于变量s,它是“干净的”,非干净的版本是直接做
finaldata=realloc(finaldata,sz+32+1)。该表单只会增加finaldata的大小,因此在需要添加新零件后执行
strcpy(finaldata+sz,chunk+9)
finaldata=s用另一个指针分配指针,这不是深度副本。在两个变量中保存的地址相同(指针是地址)之后,我还发现十六进制文件中有一行的长度不是43,而是正确的数据类型,因此我创建了一个整数来检查“chunk”的长度,然后我使用该变量删除校验和,并正确调整大小和读取数据。谢谢你的帮助,我将把它标记为已回答。
#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;
}
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 $