为什么运行到文件这就终止了,文件指针都打不开

(输入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);
}


// 将编码文件以紧凑格式显示在终端上并写入文件codeprintvoid 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;
         
        }
    }


}



11

参考GPT和自己的思路:根据您提供的代码,程序在使用文件操作时可能会出现问题。在程序中使用了文件操作函数,如fopen,fclose和fprintf等。如果无法打开文件,则会在程序中输出“Failed to open file.”并返回。请检查文件路径和权限是否正确,并确保在使用文件操作函数时文件已经存在且可以访问。如果还有其他问题,请提供更详细的错误信息以便更好地解决问题。

在这段代码中,程序试图将哈夫曼树写入文件D://hfmtree.txt,但无法打开该文件并导致程序崩溃。这可能是由于文件不存在、文件路径错误、权限不足等原因导致的。您可以检查这些方面,以确保程序可以成功打开和写入该文件。
以下是可以用来检查文件是否存在的代码示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

bool fileExists(const char *fileName) {
    FILE *file = fopen(fileName, "r");
    if (file) {
        fclose(file);
        return true;
    }
    return false;
}

在主函数中,您可以像这样调用该函数来检查文件是否存在:

if (!fileExists("D://hfmtree.txt")) {
    printf("File does not exist.\n");
    return;
}

FILE *fp = fopen("D://hfmtree.txt", "w");
if (!fp) {
    printf("Failed to open file.\n");
    return;
}

// 将哈夫曼树写入文件

fclose(fp);


另外,您还可以在程序崩溃之前添加一些打印语句,以确定程序的执行到哪一步。例如,在打开文件之前添加以下语句:

printf("Before opening file.\n");


在程序崩溃之后添加以下语句:

printf("Program crashed.\n");


为什么

该回答引用ChatGPT
您好,根据您提供的代码,我发现在 select 函数中缺少了一部分代码,因此无法完整地编译和运行程序。建议您检查一下代码是否有缺失或错误,并提供完整的代码再进行调试。

另外,在您提供的代码中,没有看到文件打开失败的相关代码。如果无法打开文件,可以使用 perror 函数来查看错误信息,例如:

FILE *fp = fopen("filename.txt", "r");
if (fp == null) {
    perror("Error opening file");
    exit(EXIT_FAILURE);
}

希望这些信息能够帮助您解决问题。

你的代码中有两处可能会导致文件指针打不开。

第一处是保存哈夫曼树的时候,你将文件名写死了,如果你的电脑没有 D 盘,那么就会打不开。你可以尝试改成一个存在的文件路径。

第二处是在打开文件的时候,你没有检查文件是否成功打开。可以在打开文件之后加一个判断语句来检查是否打开成功。

你的代码中有两处可能会导致文件指针打不开。

第一处是保存哈夫曼树的时候,你将文件名写死了,如果你的电脑没有 D 盘,那么就会打不开。你可以尝试改成一个存在的文件路径。

第二处是在打开文件的时候,你没有检查文件是否成功打开。可以在打开文件之后加一个判断语句来检查是否打开成功。

问题描述:
运行到文件这里就终止了,文件指针都打不开。
解决方案:
1.检查文件路径是否正确,确保文件存在。
2.检查文件是否被其他程序占用,导致无法打开。
3.检查文件权限是否正确,是否有读写权限。
4.检查文件是否被正确关闭,避免文件指针泄漏。
5.检查代码中是否有错误,可能会导致文件无法打开。
在本代码中,出现问题的地方是在函数creathf()和savehf()中打开文件时,文件路径不正确,应该使用双斜杠"\\\\ "代替单斜杠"/",正确的路径应该是"D:\\\\hfmtree.txt"。同时,在打开文件之前,应该先判断文件是否打开成功,如果打开失败,应该及时关闭文件并返回。修改后的代码如下:
void creathf(hfnode *T,int n) {
int i;
int s;
int s1,s2;
*T = (hfnode)malloc(sizeof(Huffmantree) * (2*n-1) + 1);
//输入每棵树的权重
printf("\
请输入每棵树的数据以及权重:\
");
getchar();
for(i = 1; i <= n; i++){
(*T + i)->leftchild = 0;
(*T + i)->parent = 0;
(*T + i)->rightchild = 0;
printf("\
输入第%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");
if (!fp) {
printf("Failed to open file.\
");
fclose(fp);
return ;
}
for(i = 1;i <= n*2-1;i++) {
fprintf(fp,"%c %d %d %d %d\
",(*T + i)->data,(*T + i)->parent,(*T + i)->leftchild,(*T + i)->rightchild,(*T + i)->weight);
}
fclose(fp);
}
void savehf(hfnode T,int n){
printf("到这里没有问题");
FILE *fp = fopen("D:\\\\hfmtree.txt", "w");
if (!fp) {
printf("Failed to open file.\
");
fclose(fp);
return ;
}
for(int i = 1;i <= n*2-1;i++) {
fprintf(fp,"%c %d %d %d %d\
",T[i].data,T[i].parent,T[i].leftchild,T[i].rightchild,T[i].weight);
}
fclose(fp);
}

D://hfmtree.txt
这个是D:\hfmtree.txt

然后少了fclose


        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);
    }
   
        fclose(fp);

不知道你这个问题是否已经解决, 如果还没有解决的话:
  • 这有个类似的问题, 你可以参考下: https://ask.csdn.net/questions/267725
  • 你也可以参考下这篇文章:判断一个正整数是否为回文数
  • 除此之外, 这篇博客: 你能用多少种方法字符串中的字符反向排列,要不看看我的中的 1.递归方法(结果和题目一致,但是不满足题目所给要求,这里只是思路比较简单) 部分也许能够解决你的问题, 你可以仔细阅读以下内容或者直接跳转源博客中阅读:
    #include <stdio.h>
    #include <string.h>
    
    void reverse(char arr[], int left, int right)
    {
        if (left < right)
        {
            char tmp = arr[left];
            arr[left] = arr[right];
            arr[right] = tmp;
            reverse(arr, left + 1, right - 1);
        }
    }
    
    int main()
    {
        char arr[] = "abcdef";//[a b c d e f \0]
        int left = 0;
        int right = strlen(arr) - 1;
        reverse(arr,left,right);
        printf("%s\n", arr);
        return 0;
    }
    

    重难点:第一这里使用了库函数strlen
    第二这里自定义的函数使用了三个参数
    但是!这个思路非常清晰明了


如果你已经解决了该问题, 非常希望你能够分享一下解决方案, 写成博客, 将相关链接放在评论区, 以帮助更多的人 ^-^