数据结构作业要构造huffman树并输出文件,但是过程遇到问题,困了好几天没能解决。
如图,我尝过许多方法,文件名字符串双斜杠试过,作为变量传入也试过,但是都会发生这样的情况。但是更让我难以理解的是偶尔会成功打开并且成功写入,这就让我不知道要从哪里找问题了。
部分代码如下,程序还未完成但是可以调试部分功能了
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define ERROR 0
#define OK 1
typedef int status;
typedef struct {
unsigned int weight;
unsigned parent, lchild, rchild;
}HTNode, *HuffmanTree;
typedef char **HuffmanCode;
void Get_Info(int *n, char **charset, int **w) {
printf("请输入字符集大小:");
scanf("%d", n);
getchar();
int i, m = 2 * (*n) - 1;
*charset = (char*)malloc((*n) * sizeof(char));
*w = (int*)malloc((*n) * sizeof(int));
for (i = 0; i < *n; i++) {
printf("请输入第%d个字符及其权值(中间用空格隔开):", i + 1);
scanf("%c", (*charset)+i);
getchar();
scanf("%d", (*w)+i);
getchar();
}
}
void Select(HuffmanTree HT, int m, int *s1, int *s2) { //s1.w<s2.w
int i, temp, tag = 1;
HuffmanTree p;
for (i = 1, p = HT + 1; i <= m; p++, i++) {
if (p->parent == 0 && tag == 1) {
*s1 = i;
tag++;
}
else if (p->parent == 0 && tag == 2) { //没加else,导致同时执行
*s2 = i;
break;
}
}
if (HT[*s1].weight > HT[*s2].weight) {
temp = *s1;
*s1 = *s2;
*s2 = temp;
}
for (i = 1, p = HT + 1; i <= m; p++, i++) {
if (p->weight < HT[*s1].weight && p->parent == 0) {
*s2 = *s1;
*s1 = i;
}
else if (p->weight < HT[*s2].weight && p->weight != HT[*s1].weight && p->parent == 0)
*s2 = i;
}
}
void CreateHT(HuffmanTree *HT, int n, char *charset, int* w, char treefilename[]) {
int i, m;
int s1, s2;
FILE *Huffman;
HuffmanTree p;
//初始化
m = 2 * n - 1;
(*HT) = (HuffmanTree)malloc((m + 1) * sizeof(HuffmanCode));
for (p = *HT + 1, i = 1; i <= m; i++, p++) {
p->weight = 0;
p->parent = 0;
p->lchild = 0;
p->rchild = 0;
}
for (p = *HT + 1, i = 1; i <= n; i++, p++, w++)
p->weight = *w;
//建Huffman树
for (i = n + 1; i <= m; i++) { //调试分析1:写成i = 1,发生错误。
Select(*HT, i - 1, &s1, &s2); /*调试分析3:刚开始设置为i,导致select函数多找一位,Huffman树生成错误,应为i-1*/
(*HT)[i].weight = (*HT)[s1].weight + (*HT)[s2].weight;
(*HT)[i].lchild = s1;
(*HT)[i].rchild = s2;
(*HT)[s1].parent = i;
(*HT)[s2].parent = i;
}
//输出到Huffman文件
Huffman = fopen(treefilename, "w");
fprintf(Huffman, "W P L R\n");
for (i = 1; i <= m; i++)
fprintf(Huffman, "%d %d %d %d\n", (*HT)[i].weight, (*HT)[i].parent, (*HT)[i].lchild, (*HT)[i].rchild);
fclose(Huffman);
}
void Coding(HuffmanTree HT,HuffmanCode *HC, int n) {
int start;
unsigned int c, f;
char *cd;
(*HC) = (HuffmanCode)malloc((n + 1) * sizeof(char*));
cd = (char*)malloc(n * sizeof(char));
cd[n - 1] = '\0';
for (int i = 1; i <= n; ++i) {
start = n - 1;
for (c = i, f = HT[i].parent; f != 0; c = f, f = HT[f].parent) {
if (HT[f].lchild == c)
cd[--start] = '0';
else
cd[--start] = '1';
}
(*HC)[i] = (char*)malloc((n - start) * sizeof(char));
strcpy((*HC)[i], &cd[start]);
}
free(cd);
}
status CodeFile(HuffmanCode HC, char *textfilename, char *codefilename, char *charset) {
FILE *CodeFile, *TextFile;
char text[1000],code[5000];
int length = 0, i, j;
TextFile = fopen(textfilename, "r");
if (TextFile == NULL) {
printf("正文文件不存在。请重试\n");
return ERROR;
}
while ((text[length] = fgetc(TextFile)) != EOF)
length++;
fclose(TextFile);
CodeFile = fopen(codefilename, "w");
for (i = 0; i < length; i++) {
j = 0;
while (charset[j] != text[i])
j++;
j++;
fputs(HC[j], CodeFile);
}
fclose(CodeFile);
return OK;
}
status Get_HT(HuffmanTree *HT, char *treefilename, int *n) {
int status;
char garbage[100];
FILE *Huffman;
HuffmanTree p ,q;
(*n) = 0;
p = (HuffmanTree)malloc(sizeof(HuffmanCode)*2);
Huffman = fopen(treefilename, "r");
if (Huffman == NULL) {
printf("文件不存在!");
status = ERROR;
}
else {
(*HT) = (HuffmanTree)malloc(sizeof(HTNode));
for (int i = 0; i < 100;i++) {
fgets(garbage, 37, Huffman);
puts(garbage);
printf("*%d*", i);
}
while ((fscanf(Huffman ,"%d %d %d %d", &(p[*n+1].weight), &(p[*n + 1].parent), &(p[*n + 1].lchild), &(p[*n + 1].rchild)))!=EOF) {//eof标识文件输入结束
(*n)++;
printf("%d %d %d %d\n", p[*n + 1].weight, p[*n + 1].parent, p[*n + 1].lchild, p[*n + 1].rchild);
p = (HuffmanTree)realloc(p, sizeof(HuffmanCode)*(*n + 2));
}
(*HT) = p;
status = OK;
}
return status;
}
int main() {
char *charset, treefilename[40], codefilename[40], textfilename[40], c;
int i, n, *w, status;
int op;
HuffmanTree HT = NULL;
HuffmanCode HC = NULL;
printf("姓名:陈志涛 学号:2018051234 时间:2019/10/10\n");
printf("=======================Huffman编码=======================\n");
printf("操作说明:请输入操作序号,并根据提示输入\n");
printf("菜 单:1、构建Huffman树\n");
printf(" 2、编码\n");
printf(" 3、译码\n");
printf(" 4、退出程序\n");
do {
printf("\n>>>请输入操作序号:");
scanf("%d", &op);
getchar();
switch (op){
case 1:
Get_Info(&n, &charset, &w);
printf("请输入Huffman树的文件存储地址:");
gets_s(treefilename);
CreateHT(&HT, n, charset, w, treefilename);
printf("Huffman树构建并保存成功。\n");
break;
case 2:
if (HT == NULL) {
printf("当前未构建Huffman树,是否从文件中读取(Y/N)?");
scanf("%c", &c);
getchar();
if (c == 'Y' || c == 'y') {
printf("请输入Huffman文件存储地址:");
gets_s(treefilename);
status = Get_HT(&HT, treefilename, &n);
if (status == ERROR) {
printf("获取Huffman树失败,请检查。");
break;
}
}
else
break;
}
Coding(HT, &HC, n);
printf("请输入正文文件的存储地址:");
gets_s(textfilename);
printf("请输入Huffman编码的目标存储地址:");
gets_s(codefilename);
CodeFile(HC, textfilename, codefilename, charset);
break;
}
printf("\n");
} while (1);
system("pause");
return 0;
}
希望有好心人帮帮忙解惑