文件操作-RLE:Run Length Encoding(行程长度压缩算法)

RLE:Run Length Encoding(行程长度压缩算法)

        Run Length Encoding(RLE)行程长度的原理是将字符串的连续重复字符用一个计数值和字符代替

比如,数据项为
AA AA BB C0 C0 C0 C0 FF FF FF FF FF FF (13字节)
可以视为  2*AA + BB + 4*C0 + 6*FF
压缩为  02  AA  01  BB  04 C0  06 FF  (8个字节)

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

int RLE_enc(const char * file1, const char * file2);
int RLE_dec(const char * file1, const char * file2);

int main()
{
	RLE_enc("E:\\C++programming\\file1.txt", "E:\\C++programming\\file2.txt");
	RLE_dec("E:\\C++programming\\file2.txt", "E:\\C++programming\\file3.txt");
	return 0;
}

int RLE_enc(const char * file1,const char * file2)
{
	FILE * fp1 = fopen(file1, "rb");
	if (NULL == fp1)
		return -1;

	计算文件大小,最大2^31-1/
	fseek(fp1, 0, SEEK_END);
	int  n = ftell(fp1);
	if ((n == -1)||(n == 0) )
		return -1;
	fseek(fp1, 0, SEEK_SET);
	char * text = (char *)malloc(n);  
	if (text == NULL)
		return -1;
	fread(text, 1, n, fp1);
	fclose(fp1);


	unsigned char num = 1;     //字符的个数,一个字节
	int ch =  text[0];         //字符
	int nch = 1;			   //字符的种数
	char * enctext= (char *)malloc(2*n);
	if (enctext == NULL)
		return -1;
	enctext[0] = 1;
	enctext[1] = ch;
	for (int i = 1;i < n;i++)
	{
		if (ch == text[i])
			num++;
		else
		{
			enctext[2*nch-2] = num;
			enctext[2*nch-1] = ch;
			num = 1;
			ch = text[i];
			nch++;
		}
	}
	enctext[2 * nch - 2] = num;    //最后一个字符个数
	enctext[2 * nch - 1] = ch;	   //最后一个字符
	free(text);

	FILE * fp2 = fopen(file2,"wb");
	if (NULL == fp2)
		return -1;
	fwrite(enctext,1,2*nch,fp2);
	fclose(fp2);
	free(enctext);

	return 0;
}

int RLE_dec(const char * file1, const char * file2)
{
	FILE * fp1 = fopen(file1,"rb");
	if (fp1 == NULL)
		return -1;

	FILE * fp2 = fopen(file2, "wb");
	if (fp2 == NULL)
		return -1;

	char buf[2];
	unsigned char num;
	char ch;

	while (!feof(fp1))
	{
		if(fread(buf,1,2,fp1)!=2)         //读取两个字节:字符个数+字符
			break;
		num = buf[0];
		ch = buf[1];
		char * chbuf = (char *)malloc(num);   
		for (int i = 0;i < num;i++)
			chbuf[i] = ch;
		fwrite(chbuf,1,num,fp2);
		free(chbuf);
	}
	fclose(fp1);
	fclose(fp2);
	return 0;
}

  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值