文件压缩、解压、加密(异或加密)、解密功能等都实现了,但是处理后文件命名有点不合理,采用了加前缀的方法得到处理后的文件名,应该是改变后缀名。
应该这种更好:test.txt --- >> 压缩---->> test.myzip
演示:
测试文本:
压缩率有点低,百思不得其解。。。
解压 压缩后的文本文件看是否正确,不乱码:
可以看出解压正常:
其余还有加密等操作,就不一一演示了。
源代码直接运行即可
#include
#include
#include
#include//调用GetCurrentDirectory()获得路径,以便删除文件
#include //调用clock函数计算运行时间
#define PART_LEN 10000//文件加密的最长长度
#define FILE_NAME_MAX_LEN 80//文件名称最大的长度
#define KEY_LEN 15
const char file_start[] = "MyZip_";
char file_path[110];
unsigned long file_len = 0;
int char_kinds = 0;
int USER_CT = 1000;
typedef struct Ad
{
int Id;
char Key[20];
struct Ad* next;
}Admi;
Admi *tail = NULL;//保存账号信息的尾节点
//哈夫曼树节点
typedef struct
{
int ch;
unsigned long count;//压缩时记录字符频度,解压时记录字符编码长度
char bits[256];//字符对应的哈夫曼编码,最多255个节点
int lch, rch, parent;//存放下标,利用指针数组
}HufNode, * HufTree;
HufNode huf_tree[512], tmp;//定义为全局变量,使用前初始化,调用函数
//一级函数
void menu1();//一级页面
void menu2();//二级页面
void CreateAd(Admi**head);//创建账号
void Login(Admi* head);//登录
void to_compress();//文件压缩
void to_extract();//文件解压
void to_Encrypted();//加密函数
void to_Unencrypted();//解密函数
void to_copy();//文件复制
void to_delete();//文件删除
void to_cut();//文件剪切
//二级函数:
void get_account(int* account);//自动生成账号,以确保唯一性
void saveAd(Admi* head);//储存账号信息
Admi* getAd();//读取账号信息
void operation();//二级页面,文件操作选项
void InitHafNode();//初始化哈夫曼节点
float compress(const char* file_name, const char* com_file_name);//压缩文件
int extract(const char* file_name, const char* ex_file_name);//解压文件
int copy_file(char* file_name, char* copy_file_name);//复制文件
void cut_name(const char* file_name, char* only_name);//截取文件名称,去除后缀
void cut_end_name(const char* file_name, char* end_name);//截取文件名的后缀
int Encrypted(const char* file_name, const char* encry_file_name);//加密
int Unencrypted(const char* file_name, const char* unencry_file_name, const char* password);//解密
//-----------------------函数实现区--------------------------------------
//一级函数区
void menu2()
{
printf("-----------欢迎使用文件处理小软件!----------\n\n");
printf(" 1.压缩文件\n\n");
printf(" 2.解压文件\n\n");
printf(" 3.加密文件\n\n");
printf(" 4.解密文件\n\n");
printf(" 5.删除文件\n\n");
printf(" 6.复制文件\n\n");
printf(" 7.剪切文件\n\n");
printf(" 8.返回上一级\n");
}
void menu1()
{
printf("-----------欢迎使用文件处理小软件!----------\n\n");
printf(" 1.创建管理员账号\n\n");
printf(" 2.登录账号\n\n");
printf(" 3.退出程序\n\n");
}
void CreateAd(Admi** head)//创建账号
{
int account;
char key[12], tmp[12];
get_account(&account);
printf("您的账号为:%d", account);
printf("请输入您的密码(不超过十位):\n");
scanf("%s", key);
system("cls");
printf("请再次输入您的密码,以确认无误。\n");
scanf("%s", tmp);
while (strcmp(tmp, key) != 0)
{
printf("抱歉!两次输入不一致,请检查后重新输入:\n");
printf("请输入您的密码(不超过十位):\n");
scanf("%s", key);
system("cls");
printf("请再次输入您的密码,以确认无误。\n");
scanf("%s", tmp);
}
printf("创建成功!\n");
printf("请牢记您的账号:%d\n", account);
printf("密码:%s\n", key);
Admi* p = (Admi*)malloc(sizeof(Admi));
p->next = NULL;
p->Id = account;
strcpy(p->Key, key);
if (tail)
{
tail->next = p;
tail = p;
}
else
{
*head = p;
tail = p;
}
return ;
}
void Login(Admi* head)
{
int account;
char key[KEY_LEN];
int flag = 0;
printf("请输入账号:\n");
scanf("%d", &account);
printf("请输入密码:\n");
scanf("%s", key);
while (head)
{
if (head->Id == account && strcmp(head->Key, key) == 0)
{
flag = 1;
break;
}
head = head->next;
}
if (flag)
{
printf("登陆成功!\n");
operation();
}
else
{
printf("登陆失败!\n");
return;
}
//system("pause");
}
void to_copy()//复制
{
char file_name[FILE_NAME_MAX_LEN];
char copy_file_name[FILE_NAME_MAX_LEN];
printf("请输入文件路径:\n");
scanf("%s", file_name);
printf("请问是否保存在当前路径下?\n");
printf("是(1),否(0)\n");
int select;
scanf("%d", &select);
if (select == 0)
{
printf("请输入新路径及名称:\n");
scanf("%s", copy_file_name);
}
else
{
char end_name[10];
cut_end_name(file_name, end_name);
cut_name(file_name, copy_file_name);
strcat(copy_file_name, "-副本");
strcat(copy_file_name, end_name);
}
if (copy_file(file_name, copy_file_name) == 1)
printf("复制完成!\n");
}
void to_delete()//删除
{
char file_name[FILE_NAME_MAX_LEN];
printf("请输入文件的完整路径:\n");
scanf("%s", file_name);
if (remove(file_name) == 0)printf("删除完成!\n");
else printf("删除失败\n");
}
void to_cut()//剪切
{
char file_name[FILE_NAME_MAX_LEN];
char cut_file_name[FILE_NAME_MAX_LEN];
printf("请输入文件的完整路径:\n");
scanf("%s", file_name);
printf("请输入文件剪切的目标路径:\n");
scanf("%s", cut_file_name);
if (copy_file(file_name, cut_file_name) == 1 && remove(file_name) == 0)
printf("文件剪切成功!\n");
}
int copy_file(char* file_name, char* copy_file_name)//复制文件
{
FILE* in_fp, * on_fp;
in_fp = fopen(file_name, "rb");
if (in_fp == NULL)
{
printf("文件读取失败!请检查是否写入的名称有误。\n");
return -1;
}
on_fp = fopen(copy_file_name, "wb");
if (on_fp == NULL)
{
printf("文件复制失败!请检查内存\n");
return -1;
}
unsigned char ch;
while (!feof(in_fp))
{
fread(&ch, sizeof(unsigned char), 1, in_fp);
fwrite(&ch, sizeof(unsigned char), 1, on_fp);
}
fclose(in_fp);
fclose(on_fp);
return 1;
}
void to_Encrypted()//加密
{
char file_name[30], encry_file_name[30], temp_name[10] = "en_";
printf("请输入需要加密的文件名:\n");
scanf("%s", file_name);
strcpy(encry_file_name, temp_name);
strcat(encry_file_name, file_name);
printf("是否使用默认命名:%s\n", encry_file_name);
printf("是(1),否(0)\n");
int select;
scanf("%d", &select);
if (select == 0)
{
printf("请输入加密后的文件名称:\n");
scanf("%s", encry_file_name);
}
if (Encrypted(file_name, encry_file_name) == 1)
printf("加密成功!\n");
else
printf("加密失败!\n");
}
void to_Unencrypted()//解密
{
char file_name[30], unencry_file_name[30], temp_name[10] = "un_";
char password[12];
printf("请输入需要解密的文件名:\n");
scanf("%s", file_name);
printf("请输入密钥(不超过10个字符):\n");
scanf("%10s", password);
strcpy(unencry_file_name, temp_name);
strcat(unencry_file_name, file_name);
printf("是否使用默认命名:%s\n", unencry_file_name);
printf("是(1),否(0)\n");
int select;
scanf("%d", &select);
if (select == 0)
{
printf("请输入解密后的文件名称:\n");
scanf("%s", unencry_file_name);
}
if (Unencrypted(file_name, unencry_file_name, password) == 1)
printf("解密成功!\n");
else
printf("解密失败!\n");
}
void to_compress()//压缩
{
int select;
system("cls");
while (1)
{
printf("************** 压缩页面 **************\n\n");
printf(" 1.压缩 2.压缩并加密\n\n");
printf(" 3.返回上一级\n");
scanf("%d", &select);
if (select == 1 || select == 2)break;
if (select == 3)return;
printf("输入有误,请选择正确的序号:\n");
system("pause");
system("cls");
}
system("cls");
char file_name[FILE_NAME_MAX_LEN];
char des_file_name[FILE_NAME_MAX_LEN];
char com_file_name[FILE_NAME_MAX_LEN] = "co_";
char encry_file_name[FILE_NAME_MAX_LEN] = "en_";
printf("请输入要压缩的文件名:\n");
scanf("%s", file_name);
printf("文件是否使用默认命名?\n");
printf("是(非零),否(零)\n");
int t;
scanf("%d", &t);
if (t == 0)
{
printf("请输入文件名:\n");
scanf("%s", des_file_name);
}
else
{
strcat(com_file_name, file_name);
strcpy(des_file_name, com_file_name);
}
printf("正在压缩中。。。\n");
clock_t start, end;
start = clock();
float rate;
if (select == 2)//先压缩再加密
{
rate = compress(file_name, com_file_name);
if (t == 0)//
{
Encrypted(com_file_name, des_file_name);
}
else//默认命名
{
strcat(encry_file_name, file_name);
Encrypted(com_file_name, encry_file_name);
strcpy(des_file_name, encry_file_name);
}
remove(com_file_name);//删除只压缩的文件
}
else//只有压缩
{
rate = compress(file_name, des_file_name);
}
end = clock();
if (rate <= 0)return;//异常处理
printf("压缩后文件名为:%s\n", des_file_name);
rate *= 100;
printf("压缩率为:%0.2f%%\n", rate);
printf("压缩时间为:%0.2lfs\n", (double)(end - start) / CLK_TCK);// CLK_TCK=1000
}
void to_extract()//解压
{
int select;
system("cls");
while (1)
{
printf("************** 解压页面 **************\n\n");
printf(" 1.解压 2.解密解压\n\n");
printf(" 3.返回上一级\n");
scanf("%d", &select);
if (select == 1 || select == 2)break;
if (select == 3)return;
printf("输入有误,请选择正确的序号:\n");
system("pause");
system("cls");
}
system("cls");
char file_name[FILE_NAME_MAX_LEN];
char ex_file_name[FILE_NAME_MAX_LEN] = "ex_";
char unencry_file_name[FILE_NAME_MAX_LEN] = "un_";
char password[KEY_LEN];
printf("请输入要解压的文件名:\n");
scanf("%s", file_name);
if (select == 2)
{
printf("请输入密钥:\n");
scanf("%10s", password);
strcat(unencry_file_name, file_name);
Unencrypted(file_name, unencry_file_name, password);
strcpy(file_name, unencry_file_name);//
}
printf("文件是否使用默认命名?\n");
printf("是(非零),否(零)\n");
int t;
scanf("%d", &t);
if (t == 0)
{
printf("请输入文件名:\n");
scanf("%s", ex_file_name);
}
else strcat(ex_file_name, file_name);
printf("正在解压中。。。\n");
clock_t start, end;
start = clock();
if (extract(file_name, ex_file_name) <= 0)return;//异常处理
end = clock();
if (select == 2)
{
remove(unencry_file_name);//删除
}
printf("解压后文件名为:%s\n", ex_file_name);
printf("解压时间为:%0.2lfs\n", (double)(end - start) / CLK_TCK);// CLK_TCK=1000
}
//****************************** 二级函数区 ******************************
void get_account(int* account)//自动生成账号
{
*account = ++USER_CT;
}
void cut_name(const char* file_name, char* only_name)//剪切文件名称
{
int len = strlen(file_name) - 1;
while (file_name[len] != '.')
{
len--;
}
strncpy(only_name, file_name, len);
only_name[len] = '\0';
}
void cut_end_name(const char* file_name, char* end_name)//剪切文件后缀
{
int len = strlen(file_name) - 1;
while (file_name[len] != '.')len--;
strcpy(end_name, &file_name[len]);
}
int Encrypted(const char* file_name, const char* encry_file_name)//加密函数
{
FILE* in_fp, * on_fp;
in_fp = fopen(file_name, "rb");
if (in_fp == NULL)
{
printf("文件读取失败!请检查是否写入的名称有误。\n");
return -1;
}
on_fp = fopen(encry_file_name, "wb");
if (on_fp == NULL)
{
printf("文件创建失败!请检查内存状况后重试。\n");
return -1;
}
char password[KEY_LEN], tmp[KEY_LEN];
printf("请输入密钥(不超过10个字符):\n");
scanf("%10s", password);
system("cls");
printf("请再次输入密钥,以确认无误:\n");
scanf("%10s", tmp);
if (strcmp(password, tmp) != 0)
{
while (strcmp(password, tmp) != 0)
{
printf("两次输入不一致,请重新输入:\n");
scanf("%10s", password);
system("cls");
printf("请再次输入密钥,以确认无误:\n");
scanf("%10s", tmp);
}
}
printf("密钥创建成功!\n");
if (on_fp == NULL)
{
printf("文件创建失败!请检查内存。\n");
return -1;
}
unsigned long part_ct = 0, file_len = 0;
fseek(in_fp, 0, SEEK_END);
file_len = ftell(in_fp);
rewind(in_fp);//问题一
if (file_len > PART_LEN)part_ct = PART_LEN;//最多加密长度PART_LEN
else part_ct = file_len / 10 + 1;//防止为空,0
unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (part_ct + 1));//创建动态数组以储存原文本的part_ct
fread(data, sizeof(unsigned char), part_ct, in_fp);//读入part_ct部分的文件,此时文件指针part_ct处
int password_len = strlen(password);
for (int i = 0; i < part_ct / password_len + 1; i++)//进行循环异或操作
for (int j = 0; j < password_len && (j + i * password_len) < part_ct; j++)
data[j + i * password_len] ^= password[j];
fwrite(data, sizeof(unsigned char), part_ct, on_fp);//将异或后的部分文件写入
while (!feof(in_fp))
{
unsigned char ch;
fread(&ch, sizeof(unsigned char), 1, in_fp);
fwrite(&ch, sizeof(unsigned char), 1, on_fp);
}
free(data);//释放动态内存
fclose(in_fp);
fclose(on_fp);
return 1;//成功
}
int Unencrypted(const char* file_name, const char* unencry_file_name, const char* password)//解密函数
{
FILE* in_fp, * on_fp;
in_fp = fopen(file_name, "rb");
if (in_fp == NULL)
{
printf("文件读取失败!请检查是否写入的名称有误。\n");
return -1;
}
on_fp = fopen(unencry_file_name, "wb");
if (on_fp == NULL)
{
printf("文件创建失败!请检查内存。\n");
return -1;
}
unsigned long part_ct = 0, file_len = 0;
fseek(in_fp, 0, SEEK_END);
file_len = ftell(in_fp);
rewind(in_fp);//问题一
if (file_len > PART_LEN)part_ct = PART_LEN;
else part_ct = file_len / 10 + 1;//防止为空,0
unsigned char* data = (unsigned char*)malloc(sizeof(unsigned char) * (part_ct + 1));//创建动态数组以储存原文本的part_ct
fread(data, sizeof(unsigned char), part_ct, in_fp);//读入part_ct部分的文件,此时文件指针part_ct处
int password_len = strlen(password);
for (int i = 0; i < part_ct / password_len + 1; i++)//进行循环异或操作
for (int j = 0; j < password_len && (j + i * password_len) < part_ct; j++)
data[j + i * password_len] ^= password[j];
fwrite(data, sizeof(unsigned char), part_ct, on_fp);//将异或后的部分文件写入
while (!feof(in_fp))
{
unsigned char ch;
fread(&ch, sizeof(unsigned char), 1, in_fp);
fwrite(&ch, sizeof(unsigned char), 1, on_fp);
}
free(data);//释放动态内存
fclose(in_fp);
fclose(on_fp);
return 1;//成功
}
void InitHafNode()
{
for (int i = 0; i < 512; i++)
{
huf_tree[i].parent = -1;
huf_tree[i].lch = -1;
huf_tree[i].rch = -1;
huf_tree[i].count = 0;
huf_tree[i].bits[0] = 0;
}
}
float compress(const char* filename, const char* outputfile)
{
InitHafNode();
char buf[512];
unsigned char c;
unsigned long flength;
FILE* infp, * onfp;
infp = fopen(filename, "rb");
if (infp == NULL)
{
printf("打开文件失败:%s\n", filename);
return 0; //如果打开失败,则输出错误信息
}
onfp = fopen(outputfile, "wb"); //打开压缩后存储信息的文件
if (onfp == NULL)
{
printf("打开文件失败:%s\n", outputfile);
return 0;
}
flength = 0;
while (!feof(infp))
{
fread(&c, 1, 1, infp);
huf_tree[c].count++; //读文件,统计字符出现次数
flength++; //记录文件的字符总数
}
flength--;
huf_tree[c].count--;
for (int i = 0; i < 512; i++) //HUFFMAN算法中初始节点的设置
{
if (huf_tree[i].count != 0)
huf_tree[i].ch = (unsigned char)i;
else
huf_tree[i].ch = -1;
huf_tree[i].parent = -1;
huf_tree[i].lch = huf_tree[i].rch = -1;//
}
for (int i = 0; i < 256; i++) //将节点按出现次数排序,降序
{
for (int j = i + 1; j < 256; j++)
{
if (huf_tree[i].count < huf_tree[j].count)
{
tmp = huf_tree[i];
huf_tree[i] = huf_tree[j];
huf_tree[j] = tmp;
}
}
}
int i;
for (i = 0; i < 256; i++) //统计不同字符的数量
{
if (huf_tree[i].count == 0)
break;
}
int n = i, j;
int m = 2 * n - 1;
long move, min;
for (i = n; i < m; i++)//每次增加一个新节点,赋值给i,此时pt1用作中间量
{
min = 999999999;
for (j = 0; j < i; j++)//找出当前最小
{
if (huf_tree[j].parent != -1) continue;
if (min > huf_tree[j].count)
{
move = j;
min = huf_tree[j].count;
}
}
huf_tree[i].count = huf_tree[move].count;
huf_tree[move].parent = i;
huf_tree[i].lch = move;
min = 999999999;
for (j = 0; j < i; j++)//当前次小
{
if (huf_tree[j].parent != -1) continue;
if (min > huf_tree[j].count)
{
move = j;
min = huf_tree[j].count;
}
}
huf_tree[i].count += huf_tree[move].count;
huf_tree[i].rch = move;
huf_tree[move].parent = i;
}
long f;
for (i = 0; i < n; i++) //构造HUFFMAN树,设置字符的编码
{
f = i;
huf_tree[i].bits[0] = 0;
while (huf_tree[f].parent != -1)
{
j = f;
f = huf_tree[f].parent;
if (huf_tree[f].lch == j)
{
j = strlen(huf_tree[i].bits);
memmove(huf_tree[i].bits + 1, huf_tree[i].bits, j + 1);//拷贝
huf_tree[i].bits[0] = '0';
}
else
{
j = strlen(huf_tree[i].bits);
memmove(huf_tree[i].bits + 1, huf_tree[i].bits, j + 1);
huf_tree[i].bits[0] = '1';
}
}
}
//下面的就是读原文件的每一个字符,按照设置好的编码替换文件中的字符
fseek(infp, 0, SEEK_SET); //将指针定在文件起始位置
fseek(onfp, 8, SEEK_SET); //以8位二进制数为单位进行读取
buf[0] = 0;
f = 0;//字节个数
move = 8;//开始计数
while (!feof(infp))
{
c = fgetc(infp);
f++;
for (i = 0; i < n; i++)
{
if (c == huf_tree[i].ch) break;
}
strcat(buf, huf_tree[i].bits);
j = strlen(buf);
c = 0;
while (j >= 8) //当剩余字符数量不小于8个时
{
for (i = 0; i < 8; i++) //按照八位二进制数转化成十进制ASCII码写入文件一次进行压缩
{
if (buf[i] == '1') c = (c << 1) | 1;
else c = c << 1;
}
fwrite(&c, 1, 1, onfp);//
move++;//
strcpy(buf, buf + 8);
j = strlen(buf);
}
if (f == flength)
break;
}
if (j > 0) //当剩余字符数量少于8个时
{
strcat(buf, "00000000");
for (i = 0; i < 8; i++)
{
if (buf[i] == '1') c = (c << 1) | 1;
else c = c << 1; //对不足的位数进行补零
}
fwrite(&c, 1, 1, onfp);
move++;//
}
fseek(onfp, 0, SEEK_SET); //将编码信息写入存储文件
fwrite(&flength, 1, sizeof(flength), onfp);//文件长度
fwrite(&move, sizeof(long), 1, onfp);//
fseek(onfp, move, SEEK_SET);//从文件开头偏移pt1
fwrite(&n, sizeof(long), 1, onfp);//写入字符种类数
for (i = 0; i < n; i++)
{
tmp = huf_tree[i];
fwrite(&(huf_tree[i].ch), 1, 1, onfp);
move++;//
c = strlen(huf_tree[i].bits);
fwrite(&c, 1, 1, onfp);
move++;//
j = strlen(huf_tree[i].bits);
if (j % 8 != 0) //当位数不满8时,对该数进行补零操作
{
for (f = j % 8; f < 8; f++)
strcat(huf_tree[i].bits, "0");
}
while (huf_tree[i].bits[0] != 0)
{
c = 0;
for (j = 0; j < 8; j++)
{
if (huf_tree[i].bits[j] == '1') c = (c << 1) | 1;
else c = c << 1;
}
strcpy(huf_tree[i].bits, huf_tree[i].bits + 8);
fwrite(&c, 1, 1, onfp); //将所得的编码信息写入文件
move++;//
}
}
fseek(onfp, 0, SEEK_END);
int ct = ftell(onfp);
fclose(infp); //关闭文件
fclose(onfp);
float rate = ct * 1.0 / flength;
return rate;
}
//作用:解压缩文件,并将解压后的内容写入新文件
int extract(const char* filename, const char* outputfile)
{
InitHafNode(); //初始化
char buf[255], bx[255];
unsigned char uch;
FILE* infp, * onfp;
infp = fopen(filename, "rb"); //打开文件
if (infp == NULL)
{
printf("文件读取失败!请检查文件名后重试。\n");
return 0; //若打开失败,则输出错误信息
}
onfp = fopen(outputfile, "wb"); //打开文件
if (onfp == NULL)
{
printf("文件创建失败!请检查内存后重试。\n");
return 0;
}
long flength, move, char_kinds; //01读取原来文本信息
fread(&flength, sizeof(long), 1, infp); //读取原文件长
fread(&move, sizeof(long), 1, infp); //读取pt1偏移量
fseek(infp, move, SEEK_SET); //从文件开头偏移pt1
fread(&char_kinds, sizeof(long), 1, infp); //读取字符种类数
for (int i = 0, m, j, len; i < char_kinds; i++) //02读取压缩文件内容并转换成二进制码哈夫曼编码
{
fread(&huf_tree[i].ch, 1, 1, infp);//读取字符
fread(&uch, 1, 1, infp);//读取编码长度
len = (long)uch;
huf_tree[i].count = len;
huf_tree[i].bits[0] = 0;
if (len % 8 > 0) m = len / 8 + 1;//上取整,补够整8位
else m = len / 8;//
for (j = 0; j < m; j++)
{
fread(&uch, 1, 1, infp);
move = uch;
_itoa(move, buf, 2);//按二进制转换,开头的0被忽略,要补齐
move = strlen(buf);
for (int t = 8; t > move; t--)
{
strcat(huf_tree[i].bits, "0"); //位数不足,执行前补零操作
}
strcat(huf_tree[i].bits, buf);
}
huf_tree[i].bits[len] = 0;//编码终止
}
for (int i = 0; i < char_kinds; i++) //从小到大排序
{
for (int j = i + 1; j < char_kinds; j++)
{
if (strlen(huf_tree[i].bits) > strlen(huf_tree[j].bits))
{
tmp = huf_tree[i];
huf_tree[i] = huf_tree[j];
huf_tree[j] = tmp;
}
}
}
int p = strlen(huf_tree[char_kinds - 1].bits); //最大编码长度
fseek(infp, 8, SEEK_SET); //从开头偏移8
int ct = 0;
bx[0] = 0;
int i;
while (1)
{
while (strlen(bx) < (unsigned int)p)
{
fread(&uch, 1, 1, infp);
move = uch;
_itoa(move, buf, 2);
move = strlen(buf);
for (int t = 8; t > move; t--)
{
strcat(bx, "0");
}
strcat(bx, buf);
}
for (i = 0; i < char_kinds; i++)
{
if (memcmp(huf_tree[i].bits, bx, huf_tree[i].count) == 0) break;
}
strcpy(bx, bx + huf_tree[i].count);
uch = huf_tree[i].ch;
fwrite(&uch, 1, 1, onfp);
ct++;
if (ct == flength) break;//读取完毕,feof会多读取,有误差
}
fclose(infp);
fclose(onfp);
return 1;
}
void operation()//供login()调用
{
system("cls");
int select;
while (1)
{
menu2();
scanf("%d", &select);
switch (select)
{
case 1:to_compress(); break;//先压缩后加密,节省时间
case 2:to_extract(); break;//若加密了请先输入,密钥
case 3:to_Encrypted(); break;//加密
case 4:to_Unencrypted(); break;//解密
case 5:to_delete(); break;//删除
case 6:to_copy(); break;//复制
case 7:to_cut(); break;//剪切
case 8:return;
default:printf("请输入对应的数字\n");
}
system("pause");
system("cls");
}
}
void saveAd(Admi* head)//退出程序保存信息
{
FILE* fp;
fp = fopen("账号密码.txt", "w");
if (fp == NULL)
{
printf("账号信息保存失败!\n");
return;
}
fprintf(fp, "%d\n", USER_CT);
while (head)
{
fprintf(fp, "%d %s\n", head->Id, head->Key);
head = head->next;
}
fclose(fp);
system("pause");
}
Admi* getAd()//读取账号信息
{
FILE* fp;
fp = fopen("账号密码.txt", "a+");
if (fp == NULL)
{
printf("账号信息读取失败!\n");
exit(1);
return NULL;
}
Admi* tmp, * head = NULL;
if (fscanf(fp, "%d\n", &(USER_CT)) == EOF)//
{
USER_CT = 1000;
fclose(fp);
return NULL;
}
while (!feof(fp))
{
tmp = (Admi*)malloc(sizeof(Admi));
tmp->next = NULL;
fscanf(fp, "%d %s\n", &(tmp->Id), tmp->Key);
if (head == NULL)
{
head = tmp;
tail = tmp;
}
else
{
tail->next = tmp;
tail = tmp;
}
}
fclose(fp);
return head;
}
//---------------------------主函数-------------------------------------
int main(int argc, char* argv[])
{
system("mode con cols=60 lines=30");
system("color 0B");//背景与字体颜色
GetCurrentDirectory(110, file_path);
strcat(file_path, "\\");//得到当前文件路径
int select = 0;
Admi* head = NULL;
head = getAd();//读取账号信息
while (1)
{
menu1();
scanf("%d", &select);
switch (select)
{
case 1:CreateAd(&head); break;
case 2:Login(head); break;
case 3:saveAd(head); exit(0); break;
default:printf("请输入对应的数字\n");
}
system("pause");
system("cls");
}
return 0;
}