C语言作业:fprintf无法写入临时文件问题求助
问题分析与解决方案
你的代码核心问题出在eraseFromFile函数的逻辑错误,以及fileLength未同步更新,导致临时文件无法写入内容,具体如下:
1. 提前return导致写入中断且资源泄漏
在eraseFromFile的while循环中,当counter == fileLength - 1时直接调用return,会直接退出函数,跳过后续的fclose调用。C语言中,文件流的缓冲区需要通过fclose或fflush才能将数据刷新到磁盘,提前return会导致已写入缓冲区的内容丢失,同时文件句柄未关闭,造成资源泄漏。
正确的做法是用continue跳过最后一行的写入,而不是直接退出函数。
2. fileLength未与链表操作同步
你在调用eraseLastData删除链表尾节点后,没有将fileLength减1。如果fileLength还是原文件的行数(9),删除节点后实际需要保留8行,但如果fileLength被错误设置为0或其他值,会导致循环一开始就触发return,根本不会写入任何内容。
需要确保每次删除链表节点后,fileLength同步减1。
3. 缺少临时文件替换原文件的步骤
你的思路是用临时文件替换原文件,但当前代码只完成了临时文件的写入,没有执行删除原文件、重命名临时文件的操作,这部分需要补充。
修正后的代码
修正后的eraseFromFile函数
void eraseFromFile(Song **tail) { FILE *fp; FILE *tempFp; char line[200]; int counter = 0; fp = fopen("playlist.txt", "r"); tempFp = fopen("temp2.txt", "w+"); if (fp == NULL || tempFp == NULL) { printf("Error: Could not open file."); // 打开失败时关闭已打开的文件 if (fp != NULL) fclose(fp); if (tempFp != NULL) fclose(tempFp); return; } while (fgets(line, 200, fp) != NULL) { // 跳过最后一行,用continue代替return if (counter == fileLength - 1) { counter++; continue; } fprintf(tempFp, "%s", line); counter++; } // 刷新缓冲区并关闭文件 fflush(tempFp); fclose(fp); fclose(tempFp); // 删除原文件并将临时文件重命名为原文件名 remove("playlist.txt"); rename("temp2.txt", "playlist.txt"); }
同步更新fileLength的eraseLastData函数
void eraseLastData(Song **tail) { Song *lastData; if ((*tail) == NULL) { printf("the playlist is currently empty..."); return; } lastData = (*tail); (*tail) = lastData->prevSong; // 处理链表只剩一个节点的情况 if ((*tail) != NULL) { (*tail)->nextSong = NULL; } lastData->prevSong = NULL; free(lastData); // 同步减少文件行数计数 fileLength--; }
额外注意事项
- 确保
fileLength在程序初始化时正确读取原文件的行数,比如启动时遍历一次文件统计行数。 - 处理链表为空的边界情况:当
fileLength减到0时,eraseFromFile应该删除原文件或者创建空文件。 - 检查
remove和rename的返回值,确保文件操作成功,避免出现异常情况。
内容的提问来源于stack exchange,提问作者k12293139
相关产品推荐
相关产品推荐

