C语言实现输入单词删除文件对应行,代码可查行但无法删除故障排查
问题定位与修正
致命错误(直接导致删除功能失效)
- 临时文件打开模式错误
你代码中database2 = fopen("database2.txt", "r");使用了只读模式r,后续的fprintf写入操作没有权限执行,临时文件始终是空的,最终替换原文件自然不会有变化。需要修改为写入模式w。 - FindLine函数逻辑错误
- 函数未正确接收输入的ID参数,内部匹配时使用的
str是未定义的变量,匹配逻辑完全失效 - 匹配到目标行后直接
return line_num,没有提前关闭打开的文件指针fp,会造成资源泄漏 return line_num后的find_result++是死代码,永远不会执行
- 输入语法错误
scanf("%s", &ID);中ID本身是字符数组,传递给scanf时自动退化为指针,不需要加取地址符&,正确写法为scanf("%s", ID);
次要可优化问题
- 不需要提前用
a模式打开临时文件再关闭,直接用w模式打开会自动创建空文件,多余操作可删除 - 循环读取文件行时,直接用
fgets的返回值作为循环条件比feof更稳妥,可避免末尾多读空行的问题 - 需要增加对
FindLine返回值的校验,如果返回0/ -1代表未找到匹配行,不需要执行后续删除逻辑
修正后核心代码示例
删除行函数
FILE *database, *database2; char str[500]; int ctr = 0; char ID[256]; database = fopen("database.txt", "r"); if(!database){ printf("Errore nell'apertura del file.\n"); getch(); return; } // 临时文件用w模式打开,直接创建空文件用于写入 database2 = fopen("database2.txt", "w"); if(!database2){ printf("Errore nell'apertura del file 2.\n"); fclose(database); getch(); return; } printf("Inserisci l'ID del libro da eliminare:"); scanf("%s", ID); int x = FindLine(ID); // 增加返回值校验,未找到则直接退出 if(x <= 0) { fclose(database); fclose(database2); remove("database2.txt"); getch(); return; } printf("%d", x); // 优化循环逻辑,直接用fgets返回值判断 while(fgets(str, 256, database) != NULL){ ctr++; if(ctr != x){ fprintf(database2, "%s", str); } } fclose(database); fclose(database2); remove("database.txt"); rename("database2.txt", "database.txt"); getch();
FindLine函数
// 明确函数参数为待匹配的ID字符串 int FindLine(char *target_id) { FILE *fp; int line_num = 1; char temp[512]; fp = fopen("database.txt", "r"); if(fp == NULL){ return -1; } while(fgets(temp, 512, fp) != NULL) { if((strstr(temp, target_id)) != NULL) { fclose(fp); // 匹配到先关闭文件再返回 return line_num; } line_num++; } printf("\nSorry, couldn't find a match.\n"); fclose(fp); return 0; }
内容的提问来源于stack exchange,提问作者user16765417
相关产品推荐
相关产品推荐

