(输入1构造哈夫曼树这里)为什么运行到文件这就终止了,文件指针都打不开。全部代码,可以直接运行,有没有人求解一下,搞了好久了
#include<stdio.h>
#include<stdlib.h>
#include <string.h>
typedef struct huffmantree {
char data;
int weight;
int leftchild;
int rightchild;
int parent;
}Huffmantree,*hfnode;
int select(Huffmantree* T,int *s1,int *s2);
void creathf(hfnode *T);
void Initalization();
int countLeafNodes(Huffmantree *root);
void saveHuffmanTree(Huffmantree *root);
Huffmantree* readHuffmanTree();
void printTree(Huffmantree *hf, int index,int level);
void treePrint();
void encodeHF();
void decode();
void compactDisplayCodeFile();
int select(Huffmantree* T,int *s1,int *s2,int NODE){
int i = 1;
int m1 = -1,m2 = -1;
int MAXNODE = NODE * 2 - 1;
while(i <= MAXNODE && m1 == -1){
if(i > NODE&&i <= MAXNODE && T[i].weight != 0 && T[i].parent == 0|| i <= NODE && T[i].parent == 0){
m1 = T[i].weight;
*s1 = i;
i++;
}else
i++;
}
while(i <= MAXNODE){
if(i > NODE&&i <= MAXNODE && T[i].weight != 0 && T[i].parent == 0 || i <= NODE && T[i].parent == 0){
if(m1 > T[i].weight){
m1 = T[i].weight;
*s1 = i;
i++;
}else i++;
}else i++;
}
i = 1;
while(i <= MAXNODE && m2 == -1){
if(i > NODE&&i <= MAXNODE && T[i].weight != 0 && T[i].parent == 0 || i <= NODE && T[i].parent == 0){
if(i == *s1){
i++;
continue;
}else{
m2 = T[i].weight;
*s2 = i;
i++;
}
}else
i++;
}
while(i <= MAXNODE){
if(i > NODE&&i <= MAXNODE && T[i].weight != 0 && T[i].parent == 0|| i <= NODE && T[i].parent == 0){
if(i != *s1){
if(m2 > T[i].weight){
m2 = T[i].weight;
*s2 = i;
i++;
}else i++;
}else i++;
}else
i++;
}
return m1 + m2;
}
void creathf(hfnode *T,int n) {//T[0]不使用,从T[1]开始
int i;
int s;
int s1,s2;
*T = (hfnode)malloc(sizeof(Huffmantree) * (2*n-1) + 1);
//输入每棵树的权重
printf("\n请输入每棵树的数据以及权重:\n");
getchar();
for(i = 1; i <= n; i++){
(*T + i)->leftchild = 0;
(*T + i)->parent = 0;
(*T + i)->rightchild = 0;
printf("\n 输入第%d个结点的数据:",i);
scanf("%c",&(*T + i)->data);
getchar();
printf(" 输入第%d个结点的权重:", i);
scanf("%d",&(*T + i)->weight);
getchar();
}
//添加额外的结点
for(i = n + 1; i <= (n*2-1); i++){
(*T + i)->weight = 0;
(*T + i)->parent = 0;
(*T + i)->leftchild = 0;
(*T + i)->rightchild = 0;
}
for(i = n + 1; i <= (n*2-1); i++){
s = select(*T,&s1,&s2,n);
(*T + i)->leftchild = s1;
(*T + i)->rightchild = s2;
(*T + i)->weight = s;
(*T + s1)->parent = i;
(*T + s2)->parent = i;
(*T + i)->data = '0';
}
printf("到这里没有问题");
//将数据存入文件
FILE *fp = fopen("D://hfmtree.txt", "w");
printf("到这里有问题,这个打印不出");
if (!fp) {
printf("Failed to open file.\n");
fclose(fp);
return ;
}
for(i = 1;i <= n*2-1;i++) {
fprintf(fp,"%c %d %d %d %d\n",(*T + i)->data,(*T + i)->parent,(*T + i)->leftchild,(*T + i)->rightchild,(*T + i)->weight);
}
}
void savehf(hfnode T,int n){
printf("到这里没有问题");
FILE *fp = fopen("D://hfmtree.txt", "w");
printf("到这里有问题,这个打印不出");
if (!fp) {
printf("Failed to open file.\n");
fclose(fp);
return ;
}
for(int i = 1;i <= n*2-1;i++) {
fprintf(fp,"%c %d %d %d %d\n",T[i].data,T[i].parent,T[i].leftchild,T[i].rightchild,T[i].weight);
}
}
void Initalization(){
int n;
printf("请输入字符集大小:");
scanf("%d",&n);
Huffmantree* root;
creathf(&root,n);
// savehf(root,n);
// saveHuffmanTree (root);
}
//计算出叶子结点
int countLeafNodes(Huffmantree *root) {
if (root == NULL) {
return 0;
}
int num = 1;
while(root[num].leftchild == 0 && root[num].rightchild == 0 ){
num ++;
}
return num - 1;
}
// 从文件中加载哈夫曼树
Huffmantree* readHuffmanTree() {
FILE *fp = fopen("D://hfmtree.txt", "r");
if (!fp) {
printf("无法加载哈夫曼树文件!\n");
fclose(fp);
exit(1);
}
int num=1;
Huffmantree *root = (hfnode)malloc(sizeof(Huffmantree) * 100 );
while(fscanf(fp,"%c %d %d %d %d\n",&root[num].data,&root[num].parent,&root[num].leftchild,&root[num].rightchild,&root[num].weight)!=EOF){
num++;
}
// fread(root, sizeof(Huffmantree)* (2*n-1), 1, fp);
fclose(fp);
return root;
}
//打印树,递归实现
void printTree(Huffmantree *hf, int index,int level){
FILE *fp = fopen("treeprint.txt", "w");
if (!fp) {
printf("无法加载哈夫曼树文件!\n");
fclose(fp);
exit(1);
}
if(hf[index].rightchild != 0)
printTree(hf,hf[index].rightchild,level + 1);
for(int i = 0; i < level; i++){
printf(" ");
fprintf(fp, " ");
}
printf("%c\n",hf[index].data);
fprintf(fp, "%c\n", hf[index].data);
if(hf[index].leftchild != 0)
printTree(hf,hf[index].leftchild,level + 1);
if(hf[index].leftchild == 0){
return;
}
fclose(fp);
}
void treePrint(){
printf("\n 横向输出为:\n");
// 读入哈夫曼树
Huffmantree* T = readHuffmanTree();
int NODE = countLeafNodes(T);
printTree(T,NODE*2-1,1);
}
void encodeHF(){
// 读入哈夫曼树
Huffmantree* T = readHuffmanTree();
int NODE = countLeafNodes(T);
// for(int i = i ; i <= NODE *2-1; i++){
// printf("%c",T[i].data);
// }
// 打开读入文件
FILE* readFile = fopen("tobetrans.txt", "r");
if (!readFile) {
printf("Failed to open file.\n");
return ;
}
// 打开输出文件
FILE* writeFile = fopen("codefile.txt", "w");
if (!writeFile) {
printf("Failed to open file.\n");
fclose(writeFile);
return ;
}
//接收此字符串
char str[100];
// 从文件中读取字符串
fscanf(readFile, "%s", str);
// 遍历字符串中的每个字符
//把每个字符的编码写入
char p[NODE];
int x;
int len = strlen(str);
for (int i = 0; i < len; i++) {
bool flag = true;
int top;
for(int j = 1; j <= NODE ; j++) {
if(str[i] == T[j].data){
x = j;
Huffmantree t = T[j];
top = 0;
while(t.parent != 0){
if(T[t.parent].leftchild == x){
p[top++] = '0';
}else p[top++] = '1';
x = t.parent;
t = T[t.parent];
}
char p1[top];
//将编码反转存入文件
for(int k = 0;k < top;k++){
p1[k] = p[top-k-1];
}
//写入换行
for(int r = 0; r < top; r++){
fputc(p1[r], writeFile);
}
fputc('\n', writeFile);
flag = false;
}
if(flag==false){
break;
}
}
if(flag == true){
printf("未识别出字符,请添加相应字符再继续") ;
return ;
}
}
fclose(readFile);
fclose(writeFile);
}
// 译码
void decode() {
// 从文件中读取哈夫曼树
Huffmantree *root = readHuffmanTree();
int NODE = countLeafNodes(root);
// 打开文件
FILE *fp_code = fopen("codefile.txt", "r");
if (!fp_code) {
printf("Failed to open file.\n");
return ;
}
FILE *fp_text = fopen("textfile.txt", "w");
if (!fp_text) {
printf("Failed to open file.\n");
return ;
}
Huffmantree p ;
//找到头节点
int t;
for(t = 1 ; t <= NODE*2+1 ; t++ ){
if(root[t].parent==0){
p = root[t];break;
}
}
// 读取编码并译码
char code[100];
int len = 0;
char c;
int left,right;
while ((c = fgetc(fp_code)) != EOF) {
if (c == '0' || c == '1') {
code[len++] = c;
} else if( c == '\n'){
//读取一个存入文件
for (int i = 0; i < len; i++) {
if (code[i] == '0') {
p = root[p.leftchild];
} else {
p = root[p.rightchild];
}
//为叶子结点
if (p.leftchild == 0 && p.rightchild == 0) {
fputc(p.data, fp_text);
p = root[t];
}
}
len = 0;
}
}
// 关闭文件
fclose(fp_code);
fclose(fp_text);
}
// 将编码文件以紧凑格式显示在终端上并写入文件codeprint中
void compactDisplayCodeFile() {
FILE *fpIn = fopen("codefile.txt", "r");
if (fpIn == NULL) {
fprintf(stderr, "无法打开编码文件\n");
exit(1);
}
FILE *fpOut = fopen("codeprint.txt", "w");
if (fpOut == NULL) {
fprintf(stderr, "无法打开输出文件\n");
exit(1);
}
int num=0;
char c;
while ((c = fgetc(fpIn)) != EOF){
if(c=='0' || c=='1'){
printf("%c",c);
fputc(c, fpOut);
num++;
//50个字符换行
if(num%50 == 0){
printf("\n");
fputc('\n', fpOut);
}
}
}
fclose(fpIn);
fclose(fpOut);
}
int main(){
printf("***************欢迎您***************\n");
printf("*****1:初始化 2.编码*****\n");
printf("*****3:解码 4.打印代码文件*****\n");
printf("*****5:打印哈夫曼树 6t退出.*****\n\n");
printf("***************欢迎您***************\n");
while(1){
printf("\n请选择要执行的操作:");
int choose;
scanf("%d",&choose);
switch(choose){
case 1:Initalization();break;
case 2:encodeHF();break;
case 3:decode();break;
case 4:compactDisplayCodeFile();break;
case 5:treePrint();break;
case 6:exit;break;
default:printf("输入错误\n\n");continue;
}
}
}