user-0 提问: 我写的赫夫曼译码器在编码的时候总是停止工作，求大侠帮助

回复:
user: user-1
content: 题主的编码和译码比我做得好，但你的打印哈夫曼树做得不够好： 你可以利用树节点的深度做到这个效果：

user: user-1
content: 字数太多，重新加上源代码：  #include <stdio.h> #include <stdlib.h> #include <string.h> /*定义赫夫曼树结点的结构体变量，存放结点的权值、字符、双亲、坐孩子和右孩子*/ typedef struct{     int weight;     char ch;                 //增加一个域用于存放该节点的字符     int parent, lchild, rchild; }HTNode, *HuffmanTree; typedef char **HuffmanCode; //指向赫夫曼编码的指针 /*本程序用到的函数原型*/ void welcome();    //打印操作选择界面 void HuffmanCoding(HuffmanTree &, char *, int *, int);//建立赫夫曼树的算法 void select(HuffmanTree HT, int j, int *s1, int *s2); //从目前已建好的赫夫曼树中选择parent为0且weight最小的两个结点 void Init(); //输入n个字符及其对应的权值，根据权值建立哈夫曼树 void Coding(); //编码 void Decoding(); //译码 void Print_code(); //打印译码好的代码文件 void Print_tree(); //以凹凸表形式打印哈夫曼树 int Read_tree(HuffmanTree &HT); //从文件中读入赫夫曼树 void find(HuffmanTree &HT, char *code, char *text, int i, int m);//译码时根据01字符串寻找相应叶子节点的递归算法 void Convert_tree(unsigned char T[100][100], int s, int *i, int j);//将内存中的赫夫曼树转换成凹凸表形式的赫夫曼树 HuffmanTree HT; //全局变量，指向存放赫夫曼树的存储空间 int n = 0; //全局变量，存放赫夫曼树叶子结点的数目 int main() {     char select;     while (1)     {         welcome();         scanf("%c", &select);         switch (select)         {         case 'i':         case 'I':Init(); break;         case 'c':         case 'C':Coding(); break;         case 'd':         case 'D':Decoding(); break;         case 't':         case 'T':Print_tree(); break;         case 'e':         case 'E':exit(1);         default:printf("Input error!\n");         }         getchar();     }     return 0; } void welcome() //打印操作选择界面 {     printf("             *-----------------------------------------------------*\n");     printf("             |                 哈夫曼编码译码器                    |\n");     printf("             |-----------------------------------------------------|\n");     printf("             |                                                     |\n");     printf("             |-------------------I.初始化哈夫曼树.-----------------|\n");     printf("             |-------------------C.编码.---------------------------|\n");     printf("             |-------------------D.译码.---------------------------|\n");     printf("             |-------------------T.输出哈夫曼树.-------------------|\n");     printf("             |                                                     |\n");     printf("             *-----------------------------------------------------*\n"); } /*初始化函数，输入n个字符及其对应的权值，根据权值建立哈夫曼树，并将其存于文件hfmtree中*/ void Init() {     FILE *fp;     int i, n, w[100]; //w数组存放n个字符的权值     char character[100]; //存放n个字符     printf("\n输入字符个数 n:");     scanf("%d", &n);        //输入字符集大小     printf("输入%d个字符及其对应的权值:\n", n);     for (i = 0; i < n; i++)     {         char b = getchar();         scanf("%c", &character[i]);         scanf("%d", &w[i]);           //输入n个字符和对应的权值     }     HuffmanCoding(HT, character, w, n);    //建立赫夫曼树     if ((fp = fopen("hfmtree.txt", "wb")) == NULL)         printf("Open file hfmtree.txt error!\n");     for (i = 1; i <= 2 * n - 1; i++)     {         if (fwrite(&HT[i], sizeof(HTNode), 1, fp) != 1)   //将建立的赫夫曼树存入文件hfmtree.txt中             printf("File write error!\n");     }     printf("\n建立赫夫曼树成功，已将其存于文件hfmtree.txt中\n");     fclose(fp); } //建立赫夫曼树的算法 void HuffmanCoding(HuffmanTree &HT, char *character, int *w, int n) {     int m, i, s1, s2;     HuffmanTree p;     if (n <= 1) return;     m = 2 * n - 1;     HT = (HuffmanTree) malloc((m + 1)*sizeof(HTNode));     for (p = HT + 1, i = 1; i <= n; ++i, ++p, ++character, ++w)     {         p->ch = *character;          p->weight = *w;          p->parent = 0;          p->lchild = 0;          p->rchild = 0;     }     for (; i <= m; ++i, ++p)      {          p->ch = 0;          p->weight = 0;          p->parent = 0;         p->lchild = 0;         p->rchild = 0; }     for (i = n + 1; i <= m; ++i)     {         select(HT, i - 1, &s1, &s2);         HT[s1].parent = i;         HT[s2].parent = i;         HT[i].lchild = s1;          HT[i].rchild = s2;         HT[i].weight = HT[s1].weight + HT[s2].weight;     } } /*从HT[1]到HT[j]中选择parent为0且weight最小的两个结点，用s1和s2返回其序号*/ void select(HuffmanTree HT, int j, int *s1, int *s2) {     int i;     for (i = 1; i <= j; i++)         if (HT[i].parent == 0)         {             *s1 = i;              break;         }         for (; i <= j; i++)             if ((HT[i].parent == 0) && (HT[i].weight < HT[*s1].weight))                 *s1 = i;         HT[*s1].parent = 1;         for (i = 1; i <= j; i++)             if (HT[i].parent == 0)             {                 *s2 = i; break;             }             for (; i <= j; i++)                 if ((HT[i].parent == 0) && (i != *s1) && (HT[i].weight < HT[*s2].weight))                     *s2 = i; } void Coding() {     FILE *fp, *fw;     int i, f, c, start;     char *cd;     HuffmanCode HC;     if (n == 0)         n = Read_tree(HT);//从文件hfmtree.txt中读入赫夫曼树,返回叶子结点数     {         HC = (HuffmanCode) malloc((n + 1)*sizeof(char*) );         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) );                 strcpy(HC[i], &cd[start]);         }         free(cd);     }     if ((fp = fopen("tobetrans.txt", "r")) == NULL)         printf("Open file tobetrans.txt error!\n");     if ((fw = fopen("codefile.txt", "w+")) == NULL)         printf("Open file codefile.txt error!\n");     char temp;     fscanf(fp, "%c", &temp); //从文件读入第一个字符     while (!feof(fp))     {         for (i = 1; i <= n; i++)             if (HT[i].ch == temp) break;             for (int r = 0; HC[i][r] != '\0'; r++)             fputc(HC[i][r], fw);         fscanf(fp, "%c", &temp);      }     fclose(fw);     fclose(fp);     printf("\n对文件hfmtree.txt编码成功,结果已存入codefile.txt中。\n\n"); } void Decoding() {     FILE *fp, *fw;     int m, i;     char *code, *text, *p;     if (n == 0)         n = Read_tree(HT);//从文件hfmtree.txt中读入赫夫曼树,返回叶子结点数     if ((fp = fopen("codefile.txt", "r")) == NULL)         printf("Open file codefile.txt error!\n");     if ((fw = fopen("textfile.txt", "w+")) == NULL)         printf("Open file textfile.txt error!\n");     code = (char *) malloc(sizeof(char) );     fscanf(fp, "%c", code);        //从文件读入一个字符     for (i = 1; !feof(fp); i++)     {         code = (char *) realloc(code, (i + 1)*sizeof(char) ); //增加空间         fscanf(fp, "%c", &code[i]);     //从文件读入下一个字符      }     code[i - 1] = '\0';     text = (char *) malloc(100 * sizeof(char) );     p = text;     m = 2 * n - 1;     if (*code == '0')         find(HT, code, text, HT[m].lchild, m);   //从根节点的左子树去找     else         find(HT, code, text, HT[m].rchild, m);   //从根节点的右子树去找     for (i = 0; p[i] != '\0'; i++) //把译码好的字符存入文件textfile.txt中         fputc(p[i], fw);     fclose(fp);     fclose(fw);     printf("\n对codefile.txt文件译码成功，结果已存入textfile.txt文件。\n\n"); } /*将文件codefi1e以紧凑格式显示在终端上,每行50个代码。同时将此字符形式的编码文件写入文件codeprint中。*/ /*将已在内存中的哈夫曼树以凹凸表形式显示在屏幕上，同时将此字符形式的哈夫曼树写入文件treeprint中。*/ void Print_tree() {     unsigned char T[100][100];     int i, j, m = 0;     FILE *fp;     if (n == 0)         n = Read_tree(HT);//从文件hfmtree.txt中读入赫夫曼树,返回叶子结点数      Convert_tree(T, 0, &m, 2 * n - 1); //将内存中的赫夫曼树转换成凹凸表形式的树，存于数组T中     if ((fp = fopen("treeprint.txt", "wb+")) == NULL)         printf("Open file treeprint.txt error!\n");     printf("\n以凹凸表形式打印已建好的赫夫曼树：\n");     for (i = 1; i <= 2 * n - 1; i++)     {         for (j = 0; T[i][j] != 0; j++)         {             if (T[i][j] == ' ') { printf(" "); fputc(T[i][j], fp); }             else             {                 printf("%d", T[i][j]); fprintf(fp, "%d\n", T[i][j]);             }         }         printf("\n");     }     fclose(fp);     printf("\n此字符形式的哈夫曼树已写入文件treeprint.txt中.\n\n");  } /*从文件hfmtree.txt中读入赫夫曼树，返回叶子节点数*/ int Read_tree(HuffmanTree &HT) {     FILE *fp;     int i, n;     HT = (HuffmanTree) malloc(sizeof(HTNode));     if ((fp = fopen("hfmtree.txt", "rb")) == NULL)         printf("Open file hfmtree.txt error!\n");     for (i = 1; !feof(fp); i++)     {         HT = (HuffmanTree) realloc(HT, (i + 1)*sizeof(HTNode)); //增加空间         fread(&HT[i], sizeof(HTNode), 1, fp); //读入一个节点信息     }     fclose(fp);     n = (i - 1) / 2;     return n; } /*译码时根据01字符串寻找相应叶子节点的递归算法*/ void find(HuffmanTree &HT, char *code, char *text, int i, int m) {      if (*code != '\0') //若译码未结束     {         code++;         if (HT[i].lchild == 0 && HT[i].rchild == 0)   //若找到叶子节点         {             *text = HT[i].ch; //将叶子节点的字符存入text中             text++;             if ((*code == '0'))                 find(HT, code, text, HT[m].lchild, m); //继续从根节点的左子树找             else                 find(HT, code, text, HT[m].rchild, m); //继续从根节点的右子树找         }         else   //如果不是叶子节点             if (*code == '0')                 find(HT, code, text, HT[i].lchild, m);   //从该节点的左子树去找             else                 find(HT, code, text, HT[i].rchild, m);   //从该节点的右子树去找      }     else         *text = '\0'; //译码结束 } /*将内存中的赫夫曼树转换成凹凸表形式的赫夫曼树*/ void Convert_tree(unsigned char T[100][100], int s, int *i, int j) {     int k, l;     l = ++(*i);     for (k = 0; k < s; k++)         T[l][k] = ' ';     T[l][k] = HT[j].weight;     if (HT[j].lchild)         Convert_tree(T, s + 1, i, HT[j].lchild);     if (HT[j].rchild)         Convert_tree(T, s + 1, i, HT[j].rchild);     T[l][++k] = '\0'; }

user: user-1
content: 你好，我前段时间学数据结构，实验做得也是这个。 题目说明：空格的权值是186，需要说明。 小的代码错误： 145行（void select(HuffmanTree HT, int j, int *s1, int *s2)）函数：函数末尾没有花括号。 204行（void Decoding()）函数：    code[i - 1] = '\0'没有加分号。  编程错误： 初始化过程： 存放结构体时应用"wb"二进制存放，对应代码：    if ((fp = fopen("hfmtree.txt", "w")) == NULL)改成   if ((fp = fopen("hfmtree.txt", "wb")) == NULL) if ((fp = fopen("hfmtree.txt", "r")) == NULL)改成    if ((fp = fopen("hfmtree.txt", "rb")) == NULL) 编码过程： tobetran.txt,codefile.txt,textfile.txt都应该是文本文件，而不是二进制，这样才能进行修改与查看； 对应代码：    if ((fp = fopen("tobetrans.txt", "rb")) == NULL)改成    if ((fp = fopen("tobetrans.txt", "r")) == NULL)                         if ((fw = fopen("codefile.txt", "wb+")) == NULL)改成    if ((fw = fopen("codefile.txt", "w+")) == NULL)                         if ((fp = fopen("codefile.txt", "rb")) == NULL)改成    if ((fp = fopen("codefile.txt", "r")) == NULL)                         if ((fw = fopen("textfile.txt", "wb+")) == NULL)改成    if ((fw = fopen("textfile.txt", "w+")) == NULL)  调试结果图： 建哈夫曼树：  建立tobetrans.txt文件：加入原文  编码：   译码：    如果有其他错误，不能运行，可以回复我。

user: user-2
content: 遇到停止工作的的时候一般是死循环，越界，非法使用指针造成的  单步调试吧，先单步步过，遇到崩溃的地方设好断点，然后运行到断点处单步步入。

user: user-3
content: 崩溃的时候在弹出的对话框按相应按钮进入调试，按Alt+7键查看Call Stack里面从上到下列出的对应从里层到外层的函数调用历史。双击某一行可将光标定位到此次调用的源代码或汇编指令处，看不懂时双击下一行，直到能看懂为止。