基于Huffman编码的C语言解压缩文件程序(3)

/*从编码表文件读取相应信息以用来解压文件,读取信息包括编码和叶子信息*/
HCode* freFromFile(int code[],HCode *HC)
{
    int i;
    FILE *fe = fopen("C:\\dic.txt","rb");
    if(fe==NULL)
    {
        printf("词典文件不存在!");
        return NULL;
    }
        int k;
        int num[10];
        int m;
        int flag = 0;
        char * cd = (char *)malloc((256+1)*sizeof(char));
        //读取一个字节
        char c = fgetc(fe);
        for(i=1;flag!=1;i++)
        {
            //如果读取到#号键,就跳出循环,继续读取sum_bit和count���
            if(c=='#') break;
            //每一行的读取直到读到空格,然后就完成了一条huffman编码的读取
            int j = 0;
            while(c!=' ')
            {
                cd[j++] = c;
                c = fgetc(fe);
            }
            cd[j] = '\0';

//将读取到的huffman编码存入相应的二维字符数组当中去
            HC[i] = (char *)malloc((j+1)*sizeof(char));
            strcpy(HC[i],&cd[0]);
            //下面直到读取到空格键为止,读取huffman叶子节点信息,读取到的是字符,需要转换成int值
            c = fgetc(fe);

k = 0;
            while(c!='\n')
            {
                num[k++] = c-'0';
                c = fgetc(fe);
            }
            code[i] = 0;
            m = 0;
            //转换成int值,存入code[]数组当中
            for(k=k-1;k>=0;k--)
            {
                code[i]+=num[k]*powmy(10,m);
                m++;
            }
            //继续向下读取
            c = fgetc(fe);
        }
        //获取压缩文件的总bit数,以用来判断最后一次读取的是不是足够8位
        c = fgetc(fe);
        k = 0;
        while(c!='#')
        {
            num[k++] = c-'0';
            c = fgetc(fe);
        }
        //同样将读取到的char转换成int
        m = 0;
        sum_bit = 0;
        for(k=k-1;k>=0;k--)
        {
            sum_bit+=(num[k]*powmy(10,m));
            m = m + 1;
        }

c = fgetc(fe);  c = fgetc(fe);//头一个读取#,后一个才开始读取数据
        k = 0;
        while(c!='#')
        {
            num[k++] = c-'0';
            c = fgetc(fe);
        }
        //将读取到的char转换成int
        m = 0;  count = 0;
        for(k=k-1;k>=0;k--)
        {
            count+=num[k]*pow(10,m);
            m++;
        }
        fclose(fe);
        return HC;
}


/*压缩文件*/
void compress_file(char* file1,char*file2)
{
    int i,sum = 0,flag = 0,j,k = 0;
    //数组开设的不够大是最后的一个bug的成因,因为有可能这个Huffman编码很长很长
    int eight[1000];
    memset(eight,0,1000*sizeof(int));
    FILE *fo = fopen(file1,"rb");
    FILE *fw = fopen(file2,"wb");
    if(fo == NULL||fw == NULL)
    {
        printf("文件读取失败!");
        return;
    }
    //统计已经压缩的字节总数,用于计算压缩百分比
    int aa = 0;
    int sum_bytes = getSumBytes();
    while(!feof(fo))
    {
        sum = 0;
        int a = fgetc(fo);
        //每次读取一个字节就+1
        aa++;
        //读取了一个字节之后就与编码表进行比较,查找对应的编码
        for(i=1;i<=count;i++)
        {
            if(code[i] == a)
            {
                //flag作为计数器,当凑够8位之后就作为一个字节写入压缩文件
                flag+=strlen(HC[i]);
                int len = strlen(HC[i]);
                //flag 小于8的时候继续累加,直到凑够8个
                if(flag<8)
                {
                    for(j=0;j<len;j++)
                    eight[k++] = HC[i][j]-'0';/*我们存储的是字符串,是多少就是多少*/
                }
                //当flag>=8的时候,将8位写进压缩文件,同时将剩余的没有写入的huffman编码重新移到
                //eight【】数组前面去,同时修改flag
                else if(flag>=8)
                {
                    //将匹配到的huffman编码写进8位数组,直到k值为8,k值始终代表现在eight【】数组的长度
                    for(j=0;k<8;j++)
                      eight[k++] = HC[i][j]-'0';
                    //将匹配到的huffman编码的没有完全写进去的添加到后面。
                    for(;j<len;j++)
                      eight[k++] = HC[i][j]-'0';
                    //计算8位对应的int值,写入文件
                    sum+=eight[0]*128+eight[1]*64+eight[2]*32+eight[3]*16+eight[4]*8
                        +eight[5]*4+eight[6]*2+eight[7]*1;
                    //前8为置0
                    for(j=0;j<8;j++)
                      eight[j] = 0;
                    //将后面的移植到前面去
                    for(j=8;j<k;j++)
                      eight[j-8] = eight[j];
                    //重置flag与k
                    k = flag = j-8;
                    //写进文件
                    char c = sum;
                    fputc(c,fw);

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:http://www.heiqu.com/a287560f1be06e4c9967e0a3f6500edb.html