找了一天的错误就是找不到啊~~
运行第四个,输入字符时一下就出来两个,不知道是啥原因啊~~希望有大侠可以解决~~~感激不敬啊~~程序代码:
#include<stdlib.h> #include<stdio.h> #include<iostream.h> #include<iomanip.h> #include<string.h> #include<malloc.h> //===================================================== case 4 ============================================================ //typedef int TElemType; const int UINT_MAX=1000; typedef struct { int weight; int parent,lchild,rchild; }HTNode,* HuffmanTree; typedef char **HuffmanCode; //-----------全局变量----------------------- HuffmanTree HT; HuffmanCode HC; int *w,i,j,n; char *z; int flag=0; int numb=0; // -----------------求哈夫曼编码----------------------- int min(HuffmanTree t,int i) { // 函数void select()调用 int j,flag; int k=UINT_MAX; // 取k为不小于可能的值 for(j=1;j<=i;j++) if(t[j].weight<k&&t[j].parent==0) k=t[j].weight,flag=j; t[flag].parent=1; return flag; } //--------------------slect函数---------------------- void select(HuffmanTree t,int i,int &s1,int &s2) { // s1为最小的两个值中序号小的那个 int j; s1=min(t,i); s2=min(t,i); if(s1>s2) { j=s1; s1=s2; s2=j; } } // --------------算法-------------------------- void HuffmanCoding(HuffmanTree &HT,HuffmanCode &HC,int *w,int n) { // w存放n个字符的权值(均>0),构造哈夫曼树HT,并求出n个字符的哈夫曼编码HC int m,i,s1,s2,start; //unsigned c,f; int c,f; HuffmanTree p; char *cd; if(n<=1) return;//检测结点数是否可以构成树 m=2*n-1; HT=(HuffmanTree)malloc((m+1)*sizeof(HTNode)); // 0号单元未用 for(p=HT+1,i=1;i<=n;++i,++p,++w) { p->weight=*w; p->parent=0; p->lchild=0; p->rchild=0; } for(;i<=m;++i,++p) p->parent=0; for(i=n+1;i<=m;++i) // 建哈夫曼树 { // 在HT[1~i-1]中选择parent为0且weight最小的两个结点,其序号分别为s1和s2 select(HT,i-1,s1,s2); HT[s1].parent=HT[s2].parent=i; HT[i].lchild=s1; HT[i].rchild=s2; HT[i].weight=HT[s1].weight+HT[s2].weight; } // 从叶子到根逆向求每个字符的哈夫曼编码 HC=(HuffmanCode)malloc((n+1)*sizeof(char*)); // 分配n个字符编码的头指针向量([0]不用) cd=(char*)malloc(n*sizeof(char)); // 分配求编码的工作空间 cd[n-1]='\0'; // 编码结束符 for(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)); // 为第i个字符编码分配空间 strcpy(HC[i],&cd[start]); // 从cd复制编码(串)到HC } free(cd); // 释放工作空间 } //--------------初始化哈夫曼链表--------------------------------- void Initialization() { flag=1; int num; int num2; printf("下面初始化哈夫曼链表\n"); printf("请输入结点的个数n:"); cin>>num; n=num; w=(int*)malloc(n*sizeof(int)); z=(char*)malloc(n*sizeof(char)); printf("\n请依次输入%d个字符(字符型):\n(注意:必须以回车结束)\n",n); char base[2]; for(i=1;i<=n;i++) { printf("第%d个字符:",i); gets(base); *(z+i)=*base; } for(i=0;i<=n-1;i++) { printf("%c",*(z+i)); } printf("\n请依次输入%d个权值:\n(注意:必须以回车结束)\n",n); for(i=0;i<=n-1;i++) { printf("第%d个字符的权值:",i+1); scanf("%d",&num2); *(w+i)=num2; } HuffmanCoding(HT,HC,w,n); //------------------------打印编码------------------------------------------- printf("字符对应的编码为:"); for(i=1;i<=n;i++) { puts(HC[i]); } //--------------------------将哈夫曼编码写入文件------------------------ cout<<"下面将哈夫曼编码写入文件"<<endl<<"...................."<<endl; FILE *htmTree; char r[]={' ','\0'}; if((htmTree=fopen("htmTree.txt","w"))==NULL) { printf("can not open file"); return; } fputs(z,htmTree); for(i=0;i<n+1;i++) { fprintf(htmTree,"%6d",*(w+i)); fputs(r,htmTree); } for(i=1;i<=n;i++) { fputs(HC[i],htmTree); fputs(r,htmTree); } fclose(htmTree); printf("已将字符与对应编码写入根目录下文件htmTree.txt中\n"); } //---------------------获取报文并写入文件--------------------------------- void InputCode() { //请输入你想要编码的字符 FILE *tobetran; char str[100]; if((tobetran=fopen("tobetran.txt","w"))==NULL) { printf("不能打开文件"); return; } printf("请输入你想要编码的字符"); gets(str); fputs(str,tobetran); printf("获取报文成功"); fclose(tobetran); } //---------------------编码函数--------------------------------- void Encoding() { printf("下面对目录下文件tobetran.txt中的字符进行编码"); FILE *tobetran,*codefile; if((tobetran=fopen("tobetran.txt","rb"))==NULL) { printf("不能打开文件"); } if((codefile=fopen("codefile.txt","wb"))==NULL) { printf("不能打开文件"); } char *tran; i=99; tran=(char*)malloc(100*sizeof(char)); while(i==99) { if(fgets(tran,100,tobetran)==NULL) { printf("不能打开文件"); break; } for(i=0;*(tran+i)!='\0';i++) { for(j=0;j<=n;j++) { if(*(z+j-1)==*(tran+i)) { fputs(HC[j],codefile); if(j>n) { printf("字符错误,无法编码!"); break; } } } } } printf("编码工作完成,编码写入目录下的codefile.txt中"); fclose(tobetran); fclose(codefile); free(tran); } //-----------------------打印编码的函数---------------------- void Code_printing() { cout<<"下面打印根目录下文件CodePrin.txt中编码字符"<<endl; FILE * CodePrin,* codefile; if((CodePrin=fopen("CodePrin.txt","w"))==NULL) { printf("不能打开文件"); return; } if((codefile=fopen("codefile.txt","r"))==NULL) { printf("不能打开文件"); return; } char *work3; work3=(char*)malloc(51*sizeof(char)); do { if(fgets(work3,51,codefile)==NULL) { printf("不能读取文件"); break; } fputs(work3,CodePrin); puts(work3); }while(strlen(work3)==50); free(work3); printf("打印工作结束"); fclose(CodePrin); fclose(codefile); } //------------------------打印哈夫曼树的函数----------------------- void coprint(HuffmanTree start,HuffmanTree HT) { if(start!=HT) { FILE * TreePrint; if((TreePrint=fopen("TreePrint.txt","a"))==NULL) {printf("创建文件失败"); return; } numb++;//该变量为已被声明为全局变量 coprint(HT+start->rchild,HT); cout<<setw(5*numb)<<start->weight<<endl; fprintf(TreePrint,"%d\n",start->weight); coprint(HT+start->lchild,HT); numb--; fclose(TreePrint); } } void Tree_printing(HuffmanTree HT,int w) { HuffmanTree p; p=HT+w; printf("下面打印哈夫曼树"); coprint(p,HT); printf("打印工作结束"); } //------------------------主函数------------------------------------ void mainfo() { char choice; while(choice!='q') { printf("\n"); printf("\t\t***************哈夫曼编码解码系统*****************\n"); printf("\t\t***------(1)要初始化哈夫曼链表请输入'i'--------***\n"); printf("\t\t***------(2)输入要编码的字符'w' --------***\n"); printf("\t\t***------(3)要编码请输入'e' --------***\n"); printf("\t\t***------(4)要打印编码请输入'p' --------***\n"); printf("\t\t***------(5)要打印哈夫曼树请输入't' --------***\n"); printf("\t\t***------(6)要离开请输入'q' --------***\n"); printf("\t\t**************************************************\n"); if(flag==0)printf("\n请先初始化哈夫曼链表,输入'i'\n"); cin>>choice; switch(choice) { case 'i': Initialization(); break; case 'w': InputCode(); break; case 'e': Encoding(); break; case 'p': Code_printing(); break; case 't': Tree_printing(HT,2*n-1); break; case 'q': return; default: printf("input error"); } } free(z); free(w); free(HT); } //======================================================== case 1 ================================================================== int shoudsave=0; struct student { char num[10]; char name[20]; char sex[4]; int cgrade; int mgrade; int egrade; int totle; int ave; char neartime[10]; }; typedef struct node { struct student data; struct node *next; }Node,*Link; void menu1() { printf("********************************************************************************"); printf("\t1登记学生资料\t\t\t\t\t2删除学生资料\n"); printf("\t3查询学生资料\t\t\t\t\t4更新学生资料\n"); printf("\t5保存学生资料\t\t\t\t\t6展示学生资料\n"); printf("\t7统计学生成绩\t\t\t\t\t0退出系统\n"); printf("********************************************************************************\n"); } void printstart() { printf("-----------------------------------------------------------------------\n"); } void Wrong() { printf("\n---->提示:输入错误!\n"); } void Nofind() { printf("\n---->提示:没有找到该学生!\n"); } void printc() /* 本函数用于输出中文 */ { printf("学号\t 姓名 \t性别 \t英语成绩 数学成绩 C语言成绩 总分 平均分\n"); } void printe(Node *p)/* 本函数用于输出英文 */ { printf("%-10s%s\t%-10s%-10d%-10d%-6d%-6d%-7d\n",p->data.num,p->data.name,p->data.sex,p->data.egrade,p->data.mgrade,p->data.cgrade,p->data.totle,p->data.ave); } Node* Locate(Link l,char findmess[],char nameornum[]) /* 该函数用于定位连表中符合要求的接点,并返回该指针 */ { Node *r; if(strcmp(nameornum,"num")==0) /* 按学号查询 */ { r=l->next; while(r!=NULL) { if(strcmp(r->data.num,findmess)==0) return r; r=r->next; } } else if(strcmp(nameornum,"name")==0) /* 按姓名查询 */ { r=l->next; while(r!=NULL) { if(strcmp(r->data.name,findmess)==0) return r; r=r->next; } } return 0; } void Add(Link l) /* 增加学生 */ { Node *p,*r,*s; char num[10]; r=l; s=l->next; while(r->next!=NULL) r=r->next; /* 将指针置于最末尾 */ while(1) { printf("请你输入学号(以'0'返回上一级菜单:)"); scanf("%s",num); if(strcmp(num,"0")==0) break; while(s) { if(strcmp(s->data.num,num)==0) { printf("---->提示:学号为'%s'的学生已经存在,若要修改请你选择'4 修改'!\n",num); printstart(); printc(); printe(s); printstart(); printf("\n"); return; } s=s->next; } p=(Node *)malloc(sizeof(Node)); strcpy(p->data.num,num); printf("请你输入姓名:"); scanf("%s",p->data.name); getchar(); printf("请你输入性别:"); scanf("%s",p->data.sex); getchar(); printf("请你输入c语言成绩:"); scanf("%d",&p->data.cgrade); getchar(); printf("请你输入数学成绩:"); scanf("%d",&p->data.mgrade); getchar(); printf("请你输入英语成绩:"); scanf("%d",&p->data.egrade); getchar(); p->data.totle=p->data.egrade+p->data.cgrade+p->data.mgrade; p->data.ave=p->data.totle / 3; /* 信息输入已经完成 */ p->next=NULL; r->next=p; r=p; shoudsave=1; } } //------------------------------------------------------------------------------------------------------------------------ void Qur(Link l) /* 查询学生 */ { int sel; char findmess[20]; Node *p; if(!l->next) { printf("\n---->提示:没有资料可以查询!\n"); return; } printf("\n---->1按学号查找\n---->2按姓名查找\n"); scanf("%d",&sel); if(sel==1)/* 学号 */ { printf("请你输入要查找的学号:"); scanf("%s",findmess); p=Locate(l,findmess,"num"); if(p) { printf("\t\t\t\t查找结果\n"); printstart(); printc(); printe(p); printstart(); } else Nofind(); } else if(sel==2) /* 姓名 */ { printf("请你输入要查找的姓名:"); scanf("%s",findmess); p=Locate(l,findmess,"name"); if(p) { printf("\t\t\t\t查找结果\n"); printstart(); printc(); printe(p); printstart(); } else Nofind(); } else Wrong(); } //------------------------------------------------------------------------------------------------------- void Del(Link l) /* 删除 */ { int sel; Node *p,*r; char findmess[20]; if(!l->next) { printf("\n----->提示:没有资料可以删除!\n"); return; } printf("\n----->1按学号删除\n----->2按姓名删除\n"); scanf("%d",&sel); if(sel==1) { printf("请你输入要删除的学号:"); scanf("%s",findmess); p=Locate(l,findmess,"num"); if(p) { r=l; while(r->next!=p) r=r->next; r->next=p->next; free(p); printf("\n----->提示:该学生已经成功删除!\n"); shoudsave=1; } else Nofind(); } else if(sel==2) { printf("请你输入要删除的姓名:"); scanf("%s",findmess); p=Locate(l,findmess,"name"); if(p) { r=l; while(r->next!=p) r=r->next; r->next=p->next; free(p); printf("\n----->提示:该学生已经成功删除!\n"); shoudsave=1; } else Nofind(); } else Wrong(); } //---------------------------------------------------------------------------------------------------------- void Modify(Link l) { Node *p; char findmess[20]; if(!l->next) { printf("\n----->提示:没有资料可以修改!\n"); return; } printf("请你输入要修改的学生学号:"); scanf("%s",findmess); p=Locate(l,findmess,"num"); if(p) { printf("请你输入新学号(原来是%s):",p->data.num); scanf("%s",p->data.num); printf("请你输入新姓名(原来是%s):",p->data.name); scanf("%s",p->data.name); getchar(); printf("请你输入新性别(原来是%s):",p->data.sex); scanf("%s",p->data.sex); printf("请你输入新的c语言成绩(原来是%d分):",p->data.cgrade); scanf("%d",&p->data.cgrade); getchar(); printf("请你输入新的数学成绩(原来是%d分):",p->data.mgrade); scanf("%d",&p->data.mgrade); getchar(); printf("请你输入新的英语成绩(原来是%d分):",p->data.egrade); scanf("%d",&p->data.egrade); p->data.totle=p->data.egrade+p->data.cgrade+p->data.mgrade; p->data.ave=p->data.totle/3; printf("\n----->提示:资料修改成功!\n"); shoudsave=1; } else Nofind(); } //----------------------------------------------xiamian--------------------------------------------------- void Disp(Link l) { int count=0; Node *p; p=l->next; if(!p) { printf("\n----->提示:没有资料可以显示!\n"); return; } printf("\t\t\t\t显示结果\n"); printstart(); printc(); printf("\n"); while(p) { printe(p); p=p->next; } printstart(); printf("\n"); } //------------------------------------------------------------------------------------------------ void Tongji(Link l) { Node *pm,*pe,*pc,*pt,*pa; /* 用于指向分数最高的接点 */ Node *r=l->next; if(!r) { printf("\n----->提示:没有资料可以统计!\n"); return ; } pm=pe=pc=pt=pa=r; while(r!=NULL) { if(r->data.cgrade>=pc->data.cgrade) pc=r; if(r->data.mgrade>=pm->data.mgrade) pm=r; if(r->data.egrade>=pe->data.egrade) pe=r; if(r->data.totle>=pt->data.totle) pt=r; if(r->data.ave>=pa->data.ave) pa=r; r=r->next; } printf("------------------------------统计结果--------------------------------\n"); printf("总分最高者:\t%s %d分\n",pt->data.name,pt->data.totle); printf("平均分最高者:\t%s %d分\n",pa->data.name,pa->data.ave); printf("英语最高者:\t%s %d分\n",pe->data.name,pe->data.egrade); printf("数学最高者:\t%s %d分\n",pm->data.name,pm->data.mgrade); printf("c语言最高者:\t%s %d分\n",pc->data.name,pc->data.cgrade); printstart(); } //------------------------------------------------------------------------------------------------------------- void Save(Link l) { FILE* fp; Node *p; int flag=1,count=0; fp=fopen("c:\\student","wb"); if(fp==NULL) { printf("\n----->提示:重新打开文件时发生错误!\n"); exit(1); } p=l->next; while(p) { if(fwrite(p,sizeof(Node),1,fp)==1) { p=p->next; count++; } else { flag=0; break; } } if(flag) { printf("\n----->提示:文件保存成功.(有%d条记录已经保存.)\n",count); shoudsave=0; } fclose(fp); } void mainf() { Link l;/* 连表 */ FILE *fp; /* 文件指针 */ int sel; char ch; char jian; int count=0; Node *p,*r; l=(Node*)malloc(sizeof(Node)); l->next=NULL; r=l; fp=fopen("C:\\student","rb"); if(fp==NULL) { printf("\n----->提示:文件还不存在,是否创建?(y/n)\n"); scanf("%c",&jian); if(jian=='y'||jian=='Y') fp=fopen("C:\\student","wb"); else exit(0); } printf("\n----->提示:文件已经打开,正在导入记录......\n"); while(!feof(fp)) { p=(Node*)malloc(sizeof(Node)); if(fread(p,sizeof(Node),1,fp)) /* 将文件的内容放入接点中 */ { p->next=NULL; r->next=p; r=p; /* 将该接点挂入连中 */ count++; } } fclose(fp); /* 关闭文件 */ printf("\n----->提示:记录导入完毕,共导入%d条记录.\n",count); while(1) { menu1(); printf("请你选择操作:"); scanf("%d",&sel); if(sel==0) { if(shoudsave==1) { getchar(); printf("\n----->提示:资料已经改动,是否将改动保存到文件中(y/n)?\n"); scanf("%c",&ch); if(ch=='y'||ch=='Y') Save(l); } printf("\n---->提示:你已经退出系统,再见!\n"); break; } switch(sel) { case 1:Add(l);break; /* 增加学生 */ case 2:Del(l);break;/* 删除学生 */ case 3:Qur(l);break;/* 查询学生 */ case 4:Modify(l);break;/* 修改学生 */ case 5:Save(l);break;/* 保存学生 */ case 6:Disp(l);break;/* 统计结果*/ case 7:Tongji(l);break;/* 展示成绩*/ default: Wrong();getchar();break; } } } //========================================================== mian ======================================================= void main() { int p; while(1) { printf("\t\t^-^ ^-^ ^-^ 数据结构 课程设计 ^-^ ^-^ ^-^ \n"); printf("\t\t****** ******\n"); printf("\t\t*----- 1.成绩管理系统 -----*\n"); printf("\t\t*----- 4.哈弗曼编码、译码器 -----*\n"); printf("\t\t*----- 0.退出本程序 -----*\n"); printf("\t\t****** ******\n"); printf("\t\t^-^ ^-^ ^-^ ^-^ ^-^ ^-^ ^-^ ^-^ ^-^ ^-^ ^-^\n"); printf("\t\t*请选择(0-5):"); scanf("\n%d",&p); printf("\n"); switch(p) { case 1:mainf();break; case 2:mains();break; case 3:maint();break; case 4:mainfo();break; case 0: exit(0); } } }