您的位置:首页 > 编程语言 > C语言/C++

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

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

/*
功能:
writeBit(char *ch)把'0'和'1'组成的字符串,压缩存储二进制在bit.txt文件
bit.txt文件结构如下:开头4个字节保存了该文件存储的位数,后面的字节为存储内容

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

#include<stdio.h>
#include<string.h>
#include<stdlib.h>

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");
}




内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐