weixin_57305647 2021-06-19 00:47 采纳率: 33.3%
浏览 204
已采纳

哈夫曼树压缩,报错不能将errno_t类型的值分配到+file*类型的实体,该怎么修改解决这个问题

#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <conio.h> 
#define _CRT_SECURE_NO_WARNINGS

/*哈夫曼树结构定义*/
struct head
{
    unsigned char b;            /*定义一个字符*/
    long count;                 /*频率数据*/
    long parent, lch, rch;        /*创建哈夫曼树*/
    char bits[256];             /*哈夫曼结点*/
}header[512], tmp;


/*压缩文件*/
void yasuo()
{
    char filename[255], outputfile[255], buf[512];
    unsigned char c;
    char wenjianming[255];
    long i, j, m, n, f;
    long min1, pt1, flength;
    FILE* ifp, * ofp;
    printf("请输入文件地址及文件名:");
    gets_s(filename);
    ifp = fopen_s( &ifp,"filename", "rb");     /*打开源文件并读取*/
    while (ifp == NULL)
    {
        printf("打开文件时出错!\n");
        printf("请重新输入文件地址及文件名:");
        gets_s(filename);
        ifp = fopen_s(&ifp,"filename", "rb");
    }
    printf("请输入压缩后的文件地址和文件名及后缀:");
    gets_s(wenjianming);
    ofp = fopen_s(&ofp,"wenjianming", "wb");    /*创建并打开目的文件*/

    while (ofp == NULL)
    {
        printf("请重新输入压缩后的文件地址和文件名及后缀:");
        ofp = fopen_s(&ofp,"wenjianming", "wb");
    }
    flength = 0;

    /*读取ifp文件*/
    while (!feof(ifp))
    {
        fread(&c, 1, 1, ifp);           /*按位读取文件*/
        header[c].count++;           /*记录文件的字符总数*/
        flength++;
    }
    flength = -1;
    header[c].count = -1;             /*读取文件结束*/
    /*构造哈弗曼树,初始结点的设置*/
    for (i = 0; i < 512; i++)
    {
        if (header[i].count != 0)
            header[i].b = (unsigned char)i;
        else
            header[i].b = 0;
        header[i].parent = -1;
        header[i].lch = header[i].rch = -1;
    }
    /*按结点出现的次数排序*/
    for (i = 0; i < 256; i++)
    {
        for (j = i + 1; j < 256; j++)
        {
            if (header[i].count < header[j].count)
            {
                tmp = header[i];
                header[i] = header[j];
                header[j] = tmp;
            }
        }
    }
    /*统计不同字符的数量*/
    for (i = 0; i < 256; i++)
        if (header[i].count == 0)
            break;
    n = i;
    m = 2 * n - 1;
    for (i = n; i < m; i++)
    {
        min1 = 999999999;
        for (j = 0; j < i; j++)
        {
            if (header[j].parent != -1)
                continue;
            if (min1 > header[j].count)
            {
                pt1 = j;
                min1 = header[j].count;
                continue;
            }
        }
        header[i].count = header[pt1].count;
        header[pt1].parent = i;
        header[i].lch = pt1;
        min1 = 999999999;
        for (j = 0; j < i; j++)
        {
            if (header[j].parent != -1)
                continue;
            if (min1 > header[j].count)
            {
                pt1 = j;
                min1 = header[j].count;
                continue;
            }
        }
        header[i].count += header[pt1].count;
        header[i].rch = pt1;
        header[pt1].parent = i;
    }
    /*构造哈夫曼树,设置字符编码*/
    for (i = 0; i < n; i++)
    {
        f = i;
        header[i].bits[0] = 0;
        while (header[f].parent != -1)
        {
            j = f;
            f = header[f].parent;
            if (header[f].lch == j)
            {
                j = strlen(header[i].bits);
                memmove(header[i].bits + 1, header[i].bits, j + 1);
                header[i].bits[0] = '0';
            }
            else
            {
                j = strlen(header[i].bits);
                memmove(header[i].bits + 1, header[i].bits, j + 1);
                header[i].bits[0] = '1';
            }
        }
    } /*哈弗曼构造结束*/

    //读取源文件中的每一个字符,按照设置好的编码替换文件中的字符
    fseek(ifp, 0, SEEK_SET);					/*把文件指针指向文件的开头*/
    fwrite(&flength, sizeof(int), 1, ofp);     /*把哈弗曼代码写入ofp文件*/
    fseek(ofp, 8, SEEK_SET);                   /*以8位二进制数为单位读取*/
    buf[0] = 0;
    f = 0;
    pt1 = 8;
    while (!feof(ifp))
    {
        c = fgetc(ifp);        //从流中读取一个字符,并增加文件指针的位置
        f++;
        for (i = 0; i < n; i++)
        {
            if (c == header[i].b)
                break;
        }
        strcat_s(buf, header[i].bits); //把header[i].bits所指字符串添加到buf结尾处
        j = strlen(buf);            //计算字符串buf的长度
        c = 0;
        while (j >= 8)     /*按八位二进制数转化成十进制ASCII码写入文件一次进行压缩*/
        {
            for (i = 0; i < 8; i++)
            {
                if (buf[i] == '1') c = (c << 1) | 1;
                else c = c << 1;
            }
            fwrite(&c, 1, 1, ofp);
            pt1++;
            strcpy_s(buf, buf + 8);
            j = strlen(buf);
        }
        if (f == flength)
            break;
    }
    if (j > 0) /*剩余字符数量少于8个*/
    {
        strcat_s(buf, "00000000");
        for (i = 0; i < 8; i++)
        {
            if (buf[i] == '1') c = (c << 1) | 1;
            else c = c << 1;     /*对不足的位数补0*/
        }
        fwrite(&c, 1, 1, ofp);
        pt1++;
    }
    //将编码信息写入存储文件
    fseek(ofp, 4, SEEK_SET);     /*fseek 用于二进制方式打开的文件,移动文件读写指针位置.第一个是文件流,第3个是指针零点位置,第2个是把指针移动到的地点. */
    fwrite(&pt1, sizeof(long), 1, ofp); /*是要输出数据的地址,每次写入的位数,数据项的个数,目标文件地址*/
    fseek(ofp, pt1, SEEK_SET);
    fwrite(&n, sizeof(long), 1, ofp);
    for (i = 0; i < n; i++)
    {
        fwrite(&(header[i].b), 1, 1, ofp);
        c = strlen(header[i].bits);
        fwrite(&c, 1, 1, ofp);
        j = strlen(header[i].bits);
        if (j % 8 != 0)             /*按八位读取,位数不满8位时,对该位补0*/
        {
            for (f = j % 8; f < 8; f++)
                strcat_s(header[i].bits, "0");
        }
        while (header[i].bits[0] != 0)
        {
            c = 0;
            for (j = 0; j < 8; j++)
            {
                if (header[i].bits[j] == '1') c = (c << 1) | 1;
                else c = c << 1;
            }
            strcpy_s(header[i].bits, header[i].bits + 8);  /*把从header[i].bits+8地址开始且含有NULL结束符的字符串赋值到以header[i].bits开始的地址空间 */
            fwrite(&c, 1, 1, ofp);
        }
    }
    fclose(ifp);
    fclose(ofp);
    printf("压缩成功\n");

}
/*主函数*/
void main()
{
    printf("输入a开始压缩\n");
    printf("输入b结束压缩\n");
    while (1)
    {
        char c;
        c =_getch();
        if (c == 'a')
            yasuo();
        else
        {
            if (c == 'b')
                return;
        }
    }
}
  • 写回答

1条回答 默认 最新

  • weixin_57305647 2021-06-19 00:47
    关注

     

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 超声波模块测距控制点灯,灯的闪烁很不稳定,经过调试发现测的距离偏大
  • ¥15 import arcpy出现importing _arcgisscripting 找不到相关程序
  • ¥15 onvif+openssl,vs2022编译openssl64
  • ¥15 iOS 自定义输入法-第三方输入法
  • ¥15 很想要一个很好的答案或提示
  • ¥15 扫描项目中发现AndroidOS.Agent、Android/SmsThief.LI!tr
  • ¥15 怀疑手机被监控,请问怎么解决和防止
  • ¥15 Qt下使用tcp获取数据的详细操作
  • ¥15 idea右下角设置编码是灰色的
  • ¥15 全志H618ROM新增分区