C语言如何实现解析s19文件并保存有效数据到数组中?

[](「ApplicationData.s19」https://www.aliyundrive.com/s/avrwDVdiTDC
点击链接保存,或者复制本段内容,打开「阿里云盘」APP ,无需下载极速在线查看,视频原画倍速播放。)

需求,解析s19文件的有效内容,并保存在一个数组中返回,关于S19文件可以看这几个链接:
https://blog.csdn.net/CynalFly/article/details/122089747
https://blog.51cto.com/u_14018328/2513036
https://blog.csdn.net/qq_31868891/article/details/106887653
https://www.renrendoc.com/paper/175756562.html

仅供参考:

#include <stdio.h>
#include <string.h>
#include <conio.h>
FILE *fi,*fo;
int r;
unsigned int n,c;
long offset;
//-------------------------------------------------------
void main(int argc,char *argv[])
{
    if (argc<3) {
        cprintf("Hex2Bin srcfile desfile");
        return;
    }
    if ((fi=fopen(argv[1],"rb"))==NULL) {
        cprintf("Can not find file %s",argv[1]);
        return;
    }
    if ((fo=fopen(argv[2],"wb"))==NULL) {
        fclose(fi);
        cprintf("Can not create file %s",argv[2]);
        return;
    }
    n=0;
    while (1) {
        offset=ftell(fi);
        r=fscanf(fi,"%2x",&c);
        if (EOF==r) break;//
        if (1==r) {
            fputc(c,fo);
            n++;
        } else {//0==r
            fseek(fi,offset,SEEK_SET);//因为VC6的Release版及其VC7,8,9,10,...版的fscanf未按约定保持offset不变,所以此处必须恢复offset
            r=fgetc(fi);
            if (EOF==r) break;//
        }
    }
    fcloseall();
    cprintf("OK to Hex2Bin %d bytes.",n);
}


S19文件解析。
运行截图(只截取了解析出来的前几行数据):

img

代码如下:

#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

#define MAXLEN 10000

//2位16进制转10进制
int transHex(char* p)
{
    int s = 0;
    //第1位
    if (p[0] >= 'A' && p[0] <= 'F')
        s = (10 + p[0] - 'A') * 16;
    else
        s = (p[0] - '0') * 16;
    //第2位
    if (p[1] >= 'A' && p[1] <= 'F')
        s += (10 + p[1] - 'A') ;
    else
        s += (p[1] - '0');
    return s;
}

//计算有效数据
void TransEff(char buf[], int n, char out[])
{
    int i, j = 0;
    for (i = 0; i < n; i += 2)
    {
        out[j] = transHex(buf + i);
        printf("%c", out[j]); //临时输出
        j++;
    }
    out[j] = 0;
    printf("\n");
}



int main()
{
    char outdata[MAXLEN][40] = {0};
    int nmb = 0; //字符数

    char flag, version; //标记位和版本
    int addrNmb[] = {4,4,6,8,0,4,6,8,6,4}; //地址字段长度

    char cnt[4] = { 0 }; //count字段
    char adr[10] = { 0 }; //存储地址字段
    char data[80] = { 0 };//存储数据字段
    char check[6] = { 0 }; //校验码

    int len = 0;
    
    FILE* fp = fopen("ApplicationData.s19", "r"); 
    if (fp == 0)
    {
        printf("文件打开失败!\n");
        return 0;
    }
    //开始读文件
    while (!feof(fp))
    {
        flag = 0;
        version = 0;
        if (fread(&flag, 1, 1, fp)!=1) //读取第一个字符S
            break;

        if (flag == '\r' || flag == '\n') //忽略换行符
            continue;

        if (flag != 'S') //读取的第一个字符不是S,读取错误
            break;
        if (fread(&version, 1, 1, fp)!=1) //读取第二个字符,版本
            break;
        if (version < '0' || version >'9') //读取的第二个字符不是0~9之间的字符,读取错误
            break;

        //读取count字段
        if (fread(cnt, 1, 2, fp) != 2)
            break;
        len = transHex(cnt)*2; //得到后面字节的长度

        //读取地址
        if (fread(adr, 1, addrNmb[version - '0'], fp) != addrNmb[version - '0'])
            break;
        //读取数据部分
        if (fread(data, 1, len - addrNmb[version - '0'] - 2,fp) != (len - addrNmb[version - '0'] - 2)) //读取错误
            break;

        //读取校验码
        if (fread(check, 1, 2, fp) != 2)
            break;

        //计算有效数据
        TransEff(data, len - addrNmb[version - '0'] - 2, outdata[nmb]);
        
        nmb++;

    }
    fclose(fp);
    return 0;
}