最近做热敏打印机功能,根据打印协议系统的不断的往打印板发送数据,每次得发送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;
}