压缩指定字符

最近做热敏打印机功能,根据打印协议系统的不断的往打印板发送数据,每次得发送152字节。由于使用的是串口通信,数据量太大的话会导致数据丢失,这样就导致热敏打印机的走纸速度受到很多的限制。而客户需求的速度却大于这个速度,为了解决这个问题只能减少单次发送数据的数据量,观察每次发送的152字节数据发现,这152字节的数据中大部分数据都是0,而且还是连续的一片0。于是想到了写个压缩算法将这些0压缩一下。对于这个算法的源码如下:

 


#include <stdio.h>


/*----------------------------
 * 功能 : 将字符串中自指定的值进行压缩
 *----------------------------
 * 函数 : func
 * 访问 : public
 * 返回 : 压缩后字符串的长度,-1 :参数错误
 *
 * 参数 : src		[i]		需要压缩的字符串
 * 参数 : dst		[o]		压缩后的字符串,分配空间最短为 2 * ((len + 1) / 2) + len / 2,整形除法
 * 参数 : len		[i]		字符串长度
 * 参数 : value		[i]		压缩的值
 */
int encodefunc(const char* src, char* dst, const int len, const char value)
{
	if (NULL == src || NULL == dst || len <= 0)
	{
		printf("erro.\n");
		return -1;
	}

	unsigned char step = 0;//value连在一起的长度
	int cur = 0;//dst赋值到当前的坐标

	//i < len 不能超出压缩范围
	//step 当最后一个字节是要压缩的部分时,需要执行循环else if部分
	for (int i = 0; i < len || step; ++i)
	{
		//当字符串中的值与给定的值一致时,+1
		//判断是否超出指定范围,且值的长度不能超出char型的范围
		if (i < len && value == src[i])
		{
			step++;
		}
		//当字符串中的值与给定的值不一致时,且上一个字符为给定字符时
		else if (step)
		{
			dst[cur++] = step;
			dst[cur++] = src[i - 1];
			if (i < len)
			dst[cur++] = src[i];
			step = 0;
		}
		else
		{
			dst[cur++] = src[i];
		}
	}

	return cur;
}

/*----------------------------
 * 功能 : 将字符串中自指定的值进行解压缩
 *----------------------------
 * 函数 : func
 * 访问 : public
 * 返回 : 解压缩后字符串的长度,-1 :参数错误
 *
 * 参数 : src		[i]		已经压缩的字符串
 * 参数 : dst		[o]		解压缩后的字符串
 * 参数 : len		[i]		字符串长度
 * 参数 : value		[i]		压缩的值
 */
int decodefunc(const char* src, char* dst, const int len, const char value)
{
	if (NULL == src || NULL == dst || len <= 1)
	{
		printf("erro.\n");
		return -1;
	}

	int cur = 0;//dst赋值到当前的坐标

	//每次赋值只赋值给dst为i-1坐标的值,检查i坐标的值是否为给定的值
	for (int i = 1; i <= len; ++i)
	{
		//判断是否超出指定范围
		if (i < len && value == src[i])
		{
			for (int j = 0; j < (unsigned char)src[i - 1]; ++j)
			{
				dst[cur++] = value;
			}
			//这个字符为给定值,如果不++i的话,会导致下次循环中再次写入该值
			++i;
		}
		else
		{
			dst[cur++] = src[i - 1];
		}
	}

	return cur;
}


int main()
{
    unsigned char srcbuf[] = {0, 0, 10, 0, 2, 4, 22, 4, 0, 0, 3, 0, 0, 0, 0};
	unsigned char dstbuf0[100] = {0};
	unsigned char dstbuf1[100] = {0};
	int len;

	printf("size = %ld\n", sizeof(srcbuf)/sizeof(srcbuf[0]));
	len = encodefunc(srcbuf, dstbuf0, sizeof(srcbuf)/sizeof(srcbuf[0]), 0);
	printf("len = %d\n", len);

	len = decodefunc(dstbuf0, dstbuf1, len, 0);
	printf("len = %d\n", len);

	if (len == sizeof(srcbuf)/sizeof(srcbuf[0]))
	{
		for (int i = 0; i < len; ++i)
		{
			printf("%4d", dstbuf1[i]);
			if (srcbuf[i] != dstbuf1[i])
			{
				printf("failed.\n");
				return -1;
			}
		}
		printf("success.\n");
	}

	return 0;

}

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值