C语言二进制数压缩成字母,c语言实现把‘0’和‘1’字符串转化为二进制压缩保存成二进制文件...

数据结构的huffman编码类似这个功能,网上找了下比较少,不太满足我的要求,于是就自己写了个。方法可能不是最好的,希望有心人能指点下,本人无敌菜鸟一个。

/*

功能:

writeBit(char *ch)把'0'和'1'组成的字符串,压缩存储二进制在bit.txt文件

bit.txt文件结构如下:开头4个字节保存了该文件存储的位数,后面的字节为存储内容

readBit()把二进制文件bit.txt恢复成字符串。

*/

#include

#include

#include

void writeBit(char *ch);

void readBit();

int main()

{

char ch[500];

scanf("%s", ch);

writeBit(ch);

readBit();

return 0;

}

void writeBit(char *ch)

{

int i;

int j;

char dest;

int count = 0; //计算字符串个数

int num; //存储字符需要的多少个字节

int left;//字符串剩余不足8位的个数

FILE *fp = NULL;

char *p = NULL;

if (NULL == (fp = fopen("bit.txt", "wb")))

{

printf("open file error\n");

}

for (i = 0; ch[i] != 0; i++)

{

count++; //统计字符个数

}

num = count / 8;

left = count % 8;

printf("\n字符串共有字符%d个,占%d字节\n存储成bit.txt文件后,占%d字节\n", count, count,

(left != 0?4+num + 1 : 4+num));

if (left == 0)//如果left为0,那么num个字节刚好能够存放,否则需要num + 1字节

{

p = (char *)malloc(sizeof(char) * num);

memset(p, 0, num);

}

else

{

p = (char *)malloc(sizeof(char) * (num + 1));

memset(p, 0, num + 1);

}

j = -1;

for (i = 0; i < count; i++)//位运算,每8个字符以2进制的形式储存在一个字符中

{

if (i % 8 == 0)

{

j++;

}

p[j] <<= 1;

ch[i] -= '0';

p[j] |= ch[i];

}

if (left != 0) //如果left不为0,需要把剩余的几个位向左边靠拢

{

p[j] <<= 8 - left; //例如left为2,即00000011,需要左移6位变为11000000

fwrite(&count, sizeof(count), 1, fp);

fwrite(p, 1, num + 1 , fp);

}

else

{

fwrite(&count, sizeof(count), 1, fp);

fwrite(p, 1, num , fp);

}

fclose(fp);

}

void readBit()

{

FILE *fp = NULL;

int count;

int num;

int left;

int i, j;

unsigned char flag = 128;//即0b1000000,用于做位运算 ,注意要用无符号的字符型

char *p = NULL;

if (NULL == (fp = fopen("bit.txt", "rb")))

{

printf("open file error\n");

}

fread(&count, sizeof(count), 1, fp);

num = count / 8;

left = count % 8;

if (left == 0)

{

p = (char *)malloc(sizeof(char) * num);

fread(p, 1, num, fp);

}

else

{

p = (char *)malloc(sizeof(char) * (num + 1));

fread(p, 1, num + 1, fp);

}

fclose(fp);

j = -1;

printf("\nbit.txt文件存储的二进制为:\n");

for (i = 0; i < count; i++)

{

if (i % 8 == 0)

{

j++;

flag = 128;

}

if ((p[j] & flag))//通过改变flag字符2进制1的位置判读,一个字节哪个位是1,哪个位是0

{//并输出字符形式

printf("1");

flag /= 2;

}

else

{

printf("0");

flag /= 2;

}

}

printf("\n");

}

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

  • 4
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值