2201_76125047 2022-12-30 17:40 采纳率: 100%
浏览 77
已结题

写二进制文件改代码C语言避免死循环

问题遇到的现象和发生背景

目前这个代码while循环 while (!feof(pfBin1))总是死循环,能不能在不报错的情况下改成继续往下处理读写

遇到的现象和发生背景,请写出第一个错误信息
用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct st_ocp
{
    unsigned char header;
    unsigned char version;
    unsigned char plen[2];
    unsigned char song[2];
    unsigned char shou[2];
    unsigned char ID[2];
    unsigned char luyou[2];
    unsigned char bao[4];
}OCP;

int main() {
    OCP *poCp = NULL;
    OCP r;
    poCp = &r;
    short pLen;
    FILE *pfBin1 = fopen("C:\\ocp\\ocp_cmds.bin", "rb+");//读文件
    if (pfBin1 == NULL) {
        printf(" error \n");
        return 0;
    }
    FILE *pfBin2 = fopen("C:\\ocp\\tlv.bin", "w");//写文件
    if (pfBin2 == NULL) {
        printf(" error \n");
        return 0;
    }
    while (!feof(pfBin1)) {
        fread(&r, 16, 1, pfBin1);//先读前十六个
        if ((r.song[0] == 0x04 && r.song[1] == 0x01) && (r.shou[0] == '\x2C' && r.shou[1] == 0x01))//判断
        {
            pLen = r.plen[0] * 256 + r.plen[1];
            unsigned char *pld = NULL;
            pld = (unsigned char *) malloc(sizeof(char) * pLen);
            memset(pld, 0, sizeof(unsigned char) * pLen);
            fread(pld, pLen, 1, pfBin1);
            int ph = 0;//设游标ph
            while (ph <= pLen)
            {
                if (pld[ph + 0] == 0x00 && pld[ph + 1] == 0x28 || pld[ph + 1] == 0x29)
                {
                    fwrite(&pld[ph + 3], pld[ph + 2], 1, pfBin2);
                }
                ph = pld[ph + 2] + ph + 3;
            }
           
            free(pld);//释放内存
        } else {
            fseek(pfBin1, pLen, SEEK_CUR);/
        }
    }
    fclose(pfBin2);
    fclose(pfBin1);//关闭文件
    getchar();
    getchar();
    return 0;
}

运行结果及详细报错内容
我的解答思路和尝试过的方法,不写自己思路的,回答率下降 60%

我的思路是在 while (ph <= pLen)加上 fread(&r, 16, 1, pfBin1);fread(pld, pLen, 1, pfBin1);可是没用

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
typedef struct st_ocp
{
    unsigned char header;
    unsigned char version;
    unsigned char plen[2];
    unsigned char song[2];
    unsigned char shou[2];
    unsigned char ID[2];
    unsigned char luyou[2];
    unsigned char bao[4];
}OCP;

int main() {
    OCP *poCp = NULL;
    OCP r;
    poCp = &r;
    short pLen;
    FILE *pfBin1 = fopen("C:\\ocp\\ocp_cmds.bin", "rb+");//读文件
    if (pfBin1 == NULL) {
        printf(" error \n");
        return 0;
    }
    FILE *pfBin2 = fopen("C:\\ocp\\tlv.bin", "w");//写文件
    if (pfBin2 == NULL) {
        printf(" error \n");
        return 0;
    }
    while (!feof(pfBin1)) {
        fread(&r, 16, 1, pfBin1);//先读OCP前十六个
        if ((r.song[0] == 0x04 && r.song[1] == 0x01) && (r.shou[0] == '\x2C' && r.shou[1] == 0x01))//判断
        {
            pLen = r.plen[0] * 256 + r.plen[1];
            unsigned char *pld = NULL;
            pld = (unsigned char *) malloc(sizeof(char) * pLen);
            memset(pld, 0, sizeof(unsigned char) * pLen);//申请payload大小内存并清零
            fread(pld, pLen, 1, pfBin1);//读文件一个OCP读payload大小
            int ph = 0;//设游标ph 
            while (ph <= pLen)//游标在payload范围里面时
            {
                if (pld[ph + 0] == 0x00 && pld[ph + 1] == 0x28 || pld[ph + 1] == 0x29)
                {
                    fwrite(&pld[ph + 3], pld[ph + 2], 1, pfBin2);
                }
                ph = pld[ph + 2] + ph + 3;
            }
            fread(&r, 16, 1, pfBin1);
            fread(pld, pLen, 1, pfBin1);
            free(pld);//释放内存
        } else {
            fseek(pfBin1, pLen, SEEK_CUR);
            fread(&r, 16, 1, pfBin1);
        }
    }
    fclose(pfBin2);
    fclose(pfBin1);//关闭文件
    getchar();
    getchar();
    return 0;
}

我想要达到的结果,如果你需要快速回答,请尝试 “付费悬赏”
  • 写回答

6条回答 默认 最新

  • AIIsComing_ 2022-12-30 20:26
    关注

    可以使用 fread() 函数的返回值来避免死循环。

    fread() 函数返回实际读取的数据块数。如果返回 0,则表示已经到达文件末尾。因此,可以在循环内使用 fread() 的返回值来判断是否到达了文件末尾,从而避免死循环。

    例如,可以修改你的代码如下:

    while (!feof(pfBin1)) {
        // 读取数据块
        size_t count = fread(&r, 16, 1, pfBin1);
        if (count == 0) {
            // 到达文件末尾,退出循环
            break;
        }
        // 判断数据块是否符合条件
        if ((r.song[0] == 0x04 && r.song[1] == 0x01) && (r.shou[0] == '\x2C' && r.shou[1] == 0x01)) {
            // 执行其他操作
            ...
        } else {
            // 跳过不符合条件的数据块
            fseek(pfBin1, pLen, SEEK_CUR);
        }
    }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(5条)

报告相同问题?

问题事件

  • 系统已结题 1月12日
  • 已采纳回答 1月4日
  • 创建了问题 12月30日

悬赏问题

  • ¥15 3D多模态医疗数据集-视觉问答
  • ¥20 设计一个二极管稳压值检测电路
  • ¥15 内网办公电脑进行向日葵
  • ¥15 如何输入双曲线的参数a然后画出双曲线?我输入处理函数加上后就没有用了,不知道怎么回事去掉后双曲线可以画出来
  • ¥50 WPF Lidgren.Network.Core2连接问题
  • ¥15 soildworks装配体的尺寸问题
  • ¥100 有偿寻云闪付SDK转URL技术
  • ¥30 基于信创PC发布的QT应用如何跨用户启动后输入中文
  • ¥20 非root手机,如何精准控制手机流量消耗的大小,如20M
  • ¥15 远程安装一下vasp