用C语言读取和存储大型十六进制文件数据
我需要读取一个大的Intel十六进制文件,根据数据类型,需要将数据存储在字符串/字符数组中,以便以后使用。下面是代码,我使用chunk从十六进制文件中读取行,使用data_type检查读取行中的数据类型,sub存储从行中解析的数据,finaldata在读取时不断添加数据。但是问题是大小,最大字符数组大小是65535(如果我错了请纠正我),但我的数据大约是80000字节(120K个字符)。 如何解决这个问题(使用C语言)?还是我切换到C++或C语言更好? 提前感谢您提供的任何帮助/见解 编辑:文件中的十六进制数据如下所示: :020000040200F1 :10C00000814202D8BF32F8F10BD441C42E8004366 我需要逐行读取此数据,并基于数据类型(粗体显示,第一行显示04,第二行显示00),如果是00,则从下一个字节(数据类型后的字节)解析数据,直到最后一个字节(即校验和)之外的数据结束。然后移到下一行,如果数据类型为00,则解析数据并将其添加到以前读取的数据(字符串串联),因此变量需要存储大量最终数据(这就是我正在努力的地方,如何在单个变量中存储大量数据)用C语言读取和存储大型十六进制文件数据,c,arrays,char,c-strings,C,Arrays,Char,C Strings,我需要读取一个大的Intel十六进制文件,根据数据类型,需要将数据存储在字符串/字符数组中,以便以后使用。下面是代码,我使用chunk从十六进制文件中读取行,使用data_type检查读取行中的数据类型,sub存储从行中解析的数据,finaldata在读取时不断添加数据。但是问题是大小,最大字符数组大小是65535(如果我错了请纠正我),但我的数据大约是80000字节(120K个字符)。 如何解决这个问题(使用C语言)?还是我切换到C++或C语言更好? 提前感谢您提供的任何帮助/见解 编辑:文件
#包括
#包括
#包括
内部主(空)
{
文件*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 $