我有一个闪存转储文件,可以输出地址和数据。 我想解析数据,以便它会告诉我有效的标签 '002F0900' 列是起始地址。 有效标签的示例是“DC 08 00 06 00 00 07 26 01 25 05 09”,其中“DC 08”= 标签编号,“00 06”= 标签数据长度,“00 00”= 标签版本。标签数据在版本之后开始,在本例中为“07 26 01 25 05 09”,下一个标签将从“DC 33”开始。
我能够打印出第一个标签直到数据长度,但我不确定如何打印数据,因为我必须考虑数据是否会进入下一行,所以我不得不跳过地址不知何故。每行包含 58 列。每个地址都是 8 个字符长加上一个冒号和 2 个空格,直到下一个十六进制值开始。
我最终还必须考虑“DC”何时出现在地址栏中。 如果有人可以提供一些建议,因为我知道我这样做并不是最好的方法。我只是想让它先工作。
文本文件有数千行,如下所示:
002F0900: 09 FF DC 08 00 06 00 00 07 26 01 25 05 09 DC 33
002F0910: 00 07 00 00 1F A0 26 01 25 05 09 FF 9C 3E 00 08
002F0920: 00 01 07 DD 0A 0D 00 29 35 AD 9C 41 00 0A 00 01
002F0930: 07 DD 0A 0D 00 29 36 1C 1D 01 9C 40 00 02 00 01
002F0940: 01 00 9C 42 00 0A 00 01 07 DD 0A 0D 00 29 36 21
002F0950: 1D AD 9C 15 00 20 00 00 01 00 00 00 00 04 AD AE
002F0960: C8 0B C0 8A 5B 52 01 00 00 00 00 00 FF 84 36 BA
002F0970: 4E 92 E4 16 28 86 75 C0 DC 10 00 05 00 00 00 00
002F0980: 00 00 01 FF DC 30 00 04 00 01 00 00 00 01 9C 41
示例输出为:
Tag Number: DC 08
Address: 002E0000
Data Length: 06
Tag Data: 07 26 01 25 05 09
源代码:
#include<stdio.h>
FILE *fp;
main()
{
int i=0;
char ch;
char address[1024];
char tag_number[5];
char tag_length[4];
int number_of_addresses = 0;
long int length;
fp = fopen(FILE_NAME,"rb");
if(fp == NULL) {
printf("error opening file");
}
else {
printf("File opened\n");
while(1){
if((address[i]=fgetc(fp)) ==':')
break;
number_of_addresses++;
i++;
}
printf("\nAddress:");
for (i = 0; i < number_of_addresses;i++)
printf("%c",address[i]);
while((ch = fgetc(fp)) != 'D'){ //Search for valid tag
}
tag_number[0] = ch;
if((ch = fgetc(fp)) == 'C') //We have a valid TAG
{
tag_number[1] = ch;
tag_number[2] = fgetc(fp);
tag_number[3] = fgetc(fp);
tag_number[4] = fgetc(fp);
}
printf("\nNumber:");
for(i=0;i<5;i++)
printf("%c",tag_number[i]);
fgetc(fp); //For space
tag_length[0] = fgetc(fp);
tag_length[1] = fgetc(fp);
fgetc(fp); //For space
tag_length[2] = fgetc(fp);
tag_length[3] = fgetc(fp);
printf("\nLength:");
for(i=0;i<4;i++)
printf("%c",tag_length[i]);
length = strtol(tag_length,&tag_length[4], 16);
printf("\nThe decimal equilvant is: %ld",length);
for (i = 0;i<165;i++)
printf("\n%d:%c",i,fgetc(fp));
}
fclose(fp);
}
更新@ooga:标签是乱写的。如果我们还在逻辑中考虑无效标签,那么如果我花一些时间,我应该能够弄清楚其余部分。谢谢
最佳答案
这只是一个让您入门的想法,因为我不完全确定您需要什么。基本思想是 read_byte
将下一个两位十六进制值作为字节返回,并返回其地址。
#include <stdio.h>
#include <stdlib.h>
#define FILE_NAME "UA201_dump.txt"
void err(char *msg) {
fprintf(stderr, "Error: %s\n", msg);
exit(EXIT_FAILURE);
}
// read_byte
// Reads a single two-digit "byte" from the hex dump, also
// reads the address (if necessary).
// Returns the byte and current address through pointers.
// Returns 1 if it was able to read a byte, 0 otherwise.
int read_byte(FILE *fp, unsigned *byte, unsigned *addr_ret) {
// Save current column and address between calls.
static int column = 0;
static unsigned addr;
// If it's the beginning of a line...
if (column == 0)
// ... read the address.
if (fscanf(fp, "%x:", &addr) != 1)
// Return 0 if no address could be read.
return 0;
// Read the next two-digit hex value into *byte.
if (fscanf(fp, "%x", byte) != 1)
// Return 0 if no byte could be read.
return 0;
// Set return address to current address.
*addr_ret = addr;
// Increment current address for next time.
++addr;
// Increment column, wrapping back to 0 when it reaches 16.
column = (column + 1) % 16;
// Return 1 on success.
return 1;
}
int main() {
unsigned byte, addr, afterdc, length, version, i;
FILE *fp = fopen(FILE_NAME,"r");
if (!fp) {
fprintf(stderr, "Can't open %s\n", FILE_NAME);
exit(EXIT_FAILURE);
}
while (read_byte(fp, &byte, &addr)) {
if (byte == 0xDC) {
// Read additional bytes like this:
if (!read_byte(fp, &afterdc, &addr)) err("EOF 1");
if (!read_byte(fp, &length, &addr)) err("EOF 2");
if (!read_byte(fp, &byte, &addr)) err("EOF 3");
length = (length << 8) | byte;
if (!read_byte(fp, &version, &addr)) err("EOF 4");
if (!read_byte(fp, &byte, &addr)) err("EOF 5");
version = (version << 8) | byte;
printf("DC: %02X, %u, %u\n ", afterdc, length, version);
for (i = 0; i < length; ++i) {
if (!read_byte(fp, &byte, &addr)) err("EOF 6");
printf("%02X ", byte);
}
putchar('\n');
}
}
fclose(fp);
return 0;
}
一些解释:
每次调用 read_byte
时,它都会从十六进制转储中读取下一个打印字节(两位十六进制值)。它返回该字节以及该字节的地址。
每行有 16 个两位数的十六进制值。列号(0 到 15)在调用之间保留在静态变量中。该列在读取每个字节后递增,并在每次达到 16 时重置为 0。
只要列号为 0,它就会读取打印的地址,并在调用之间将其保留在静态变量中。它还会增加静态地址变量,以便它可以告诉您行中任意位置的字节地址(当列号不为零时)。
例如,您可以像这样使用 read_bye
,它会在单独的一行上打印每个字节值及其地址:
// after opening file as fp
while (read_byte(fp, &byte, &addr))
printf("%08X- %02X\n", addr, byte);
(并不是说这样做会有用,但要测试它,您可以使用您在问题中提供的代码段运行它。)
关于c - 如何解析十六进制转储,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24290156/