我有一个闪存转储文件,用于吐出地址和数据。 我想解析数据,以便它告诉我有效的标签 &#; 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"。
我能够将第一个标签打印到数据长度,但我不确定如何打印数据,因为我必须考虑数据是否会进入下一行,所以我&# 39; d必须以某种方式跳过地址。每行包含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:标签是任意写的。如果我们也在逻辑中考虑无效标记,那么如果我花一些时间,我应该能够弄清楚其余部分。感谢
答案 0 :(得分:1)
这只是一个让你入门的想法,因为我并不完全确定你需要什么。基本思想是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,它就会读取打印的地址,并将其保留在静态变量中的调用之间。它还会增加静态addr变量,以便它可以告诉您行中任何位置的字节地址(当列号不为零时)。
例如,你可以像这样使用read_bye
,它会在一个单独的行上打印每个字节值及其地址:
// after opening file as fp
while (read_byte(fp, &byte, &addr))
printf("%08X- %02X\n", addr, byte);
(并不是说这样做很有用,但为了测试它,您可以使用您在问题中提供的代码段来运行它。)