2、其次,将一些常见的英文表达。
3、然后,通过define,转化为中文。压缩包就是将初始文件经过压缩形成的文件,压缩文件内存更小,可以将多个文件压缩成一个文件。
#include "stdio.h"#include "string.h"
#include "malloc.h"
#define MOD_ADLER 65521
#define HASHMAX 1000
#define MAX_INT 9999999 // 最大读取数字为99999999
#define CHARBUFLEN 40960
#define DECOMPRESSINITLEN 1024
struct stringInfo
{
int No // 字符串出现的次序
char * str // 字符串
struct stringInfo * next // 下一节点
} * strTable[HASHMAX] // 用于压缩
int isCompress
char ** strTableDe // 解压缩表,用于解压缩
long deTableLen // 解压缩表长度
long curStrNum // 目前的字符串数量
// 程序初始化
void init()
{
int i
curStrNum = 1
isCompress = 1 // 压缩模式,等于0时解压缩
if(isCompress)
{
for(i=0 i<HASHMAX i++) strTable[i] = NULL
deTableLen = 0
strTableDe = NULL
}
else
{
deTableLen = DECOMPRESSINITLEN
strTableDe = (char **)malloc(deTableLen * sizeof(char *))
for(i=0 i<deTableLen i++) strTableDe[i] = NULL
}
}
// 重新申请内存
void ReMallocDeTable()
{
deTableLen <<= 1
strTableDe = (char **)realloc(strTableDe, deTableLen * sizeof(char *))
}
// 程序结束,释放内存
void over()
{
int i
struct stringInfo *pNext, *pDel
for(i=0 i<HASHMAX i++)
{
pNext = strTable[i]
while(pNext)
{
free(pNext->str)
pDel = pNext
pNext = pNext->next
free(pDel)
}
}
if(strTableDe)
{
for(i=0 i<curStrNum i++)
{
//printf("%d\t%s\n", i, strTableDe[i])
free(strTableDe[i])
}
free(strTableDe)
}
}
// adler32 校验和算法
unsigned long adler32(unsigned char * data, size_t len)
{
unsigned long a = 1, b = 0
size_t index
for (index = 0 index < len ++index)
{
a = (a + data[index]) % MOD_ADLER
b = (b + a) % MOD_ADLER
}
return (b << 16) | a
}
// 求字符串的Hash,实现快速查找, 这里用的是adler32算法,可以使用其它任何hash方法
unsigned long Hash(const char * str)
{
return adler32((unsigned char*)str, strlen(str)) % HASHMAX
}
// 复制新字符串
char * copyNewStr(const char * str)
{
char * r = (char *)malloc(strlen(str) + 1)
strcpy(r, str)
return r
}
// 取得字符串出现的次序
int getStrPos(const char * str)
{
unsigned long hash
struct stringInfo * pFirst, * pNext, * pNew
hash = Hash(str)
pNext = pFirst = strTable[hash]
while(pNext)
{
if(strcmp(pNext->str, str) == 0) return pNext->No
pNext = pNext->next
}
// 没有找到匹配的字符串
pNew = (struct stringInfo *)malloc(sizeof(struct stringInfo))
pNew->next = NULL
pNew->No = curStrNum++
pNew->str = copyNewStr(str)
if(pFirst == NULL) strTable[hash] = pNew
else
{
pNext = pFirst
while(pNext->next) pNext = pNext->next
pNext->next = pNew
}
return -1
}
// 读取字符串, 字符串以空格为结束符
// 返回负数的绝对值是读取的是字符串长度,正数为读取的数字
int ReadStr(char * out, const char * in)
{
char *po, *pn
const char *pi
int r
po = out
pi = in
while(('a' <= *pi && *pi <= 'z') || ('A' <= *pi && *pi <= 'Z') || ('0' <= *pi && *pi <= '9'))
*po++ = *pi++ // 只复制大小写字母和数字
*po = 0
// 试着转化为纯数字
r = 0
pn = out
while('0' <= *pn && *pn <= '9')
{
if(r > MAX_INT) break
r *= 10
r += *pn++ - '0'
}
if(*pn) return out - po // 未成功转化为数字
else return (r & 0x7FFFFFF) | (((po - out) & 0xF) << 27)
}
void main()
{
char readFileBuf[CHARBUFLEN], readStrBuf[CHARBUFLEN]
char *prfb
int num
FILE *fpr, *fpw
fpr = fopen("source.txt", "r") // 输入文件
fpw = fopen("object.txt", "w") // 输出文件
if(fpr == NULL || fpw == NULL) return
init()
while(!feof(fpr))
{
if(fgets(readFileBuf, CHARBUFLEN-1, fpr)==NULL) break
prfb = readFileBuf
while(*prfb)
{
num = ReadStr(readStrBuf, prfb)
if(num == 0) fputc(*prfb++, fpw) // 没有读取成功
else if(num > 0) // 读入数字
{
prfb += (num >> 27) & 0xF // 移动读取的位数
if(isCompress) fprintf(fpw, "0 %d", num & 0x7FFFFFF) // 压缩模式写入数字,前面添加个数字0
else
{
num &= 0x7FFFFFF
if(num == 0) // 如果读到数字0
{
prfb += 1
num = ReadStr(readStrBuf, prfb) // 读取下一格数据串
if(num > 0)
{
prfb += (num >> 27) & 0xF // 移动读取的位数
fprintf(fpw, "%d", num & 0x7FFFFFF)
}
else fprintf(fpw, "0 ", num & 0x7FFFFFF) // 下一个不是数字
}
else if(num < curStrNum) fprintf(fpw, "%s", strTableDe[num]) // 解压模式写入字符串
else
{
printf("Error : %d, %d\n", num, curStrNum)
fprintf(fpw, "%d", num) // num大于已知的字符串数量,写入数字
}
}
}
else
{
num = -num
prfb += num // 移动读取的位数
if(isCompress)
{
num = getStrPos(readStrBuf)
if(num < 0) fprintf(fpw, "%s", readStrBuf) // 未出现过的字符串
else fprintf(fpw, "%d", num) // 写入位置
}
else
{
fprintf(fpw, "%s", readStrBuf)
if(curStrNum >= deTableLen) ReMallocDeTable() // 解压表长度不够,重新申请空间
strTableDe[curStrNum++] = copyNewStr(readStrBuf) // 加入解压表
}
}
}
}
if(isCompress) printf("Compress successful!\n")
else printf("Decompress Successful!\n")
over()
}