(输入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;
}
}
}
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 盘,那么就会打不开。你可以尝试改成一个存在的文件路径。
第二处是在打开文件的时候,你没有检查文件是否成功打开。可以在打开文件之后加一个判断语句来检查是否打开成功。
问题描述: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);
不知道你这个问题是否已经解决, 如果还没有解决的话:#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
第二这里自定义的函数使用了三个参数
但是!这个思路非常清晰明了