fprintf函数写入失效求助:fileEdit函数无法正确保存.txt文件修改数据
问题:fprintf无法将修改后的数据写入.txt文件
我现在搞不懂为什么fprintf()没法正常工作——我的需求是改写.txt文件里的数据,但这个功能完全没生效。问题出在void fileEdit函数里:当我修改了'wT'、'wF'或者'nap'的新数值后,修改只停留在while (whT)循环里,没法执行后续逻辑完成数据保存。
以下是完整的fileEdit函数代码:
void fileEdit(FILE **file) { int dayEdit = 0; int playerChoose = 0; float nap = 0.0, wF = 0.0, wT = 0.0; while (true) { int day = 0; bool whT = true; system("CLS"); printFile(file); printf("Which day you want to edit[1 - 31, 0 to exit]: "); scanf_s("%d", &dayEdit); if (dayEdit == 0) break; while (day < dayEdit) { fscanf_s(*file, "%d %f %f %f", &day, &wF, &wT, &nap); printf("\n %d ", ftell(*file)); } while (whT) { system("CLS"); printf(" \n\n -------------------------------\n| Job Hours Managment |\n -------------------------------\n| Day | From | Till | Nap |"); printf("\n -------------------------------\n| %3d | %6.1f | %6.1f | %5.1f |", day, wF, wT, nap); printf("\n"); printf(" -------------------------------\n"); printf("\nWhat you want to edit?[1 From, 2 Till, 3 Nap, 4 Save]: "); scanf_s("%d", &playerChoose); switch (playerChoose) { case 1: printf("\nWorked from: "); scanf_s("%f", &wF); break; case 2: printf("\nWorked till: "); scanf_s("%f", &wT); break; case 3: printf("\nNap: "); scanf_s("%f", &nap); break; case 4: whT = false; default: break; } } fprintf(*file, "%d %f %f %f\n", day, wF, wT, nap); // <---- Here i want to save new data } }
解决方案
咱们一步一步来排查和修复问题:
1. 文件指针位置错误
当你用fscanf_s读取到目标天数后,文件指针已经指向了该行内容的末尾(或者下一行的开头)。这时候直接调用fprintf,会把新数据追加到文件的当前指针位置,而不是覆盖原来的行。
你需要把文件指针移回当前行的开头,这样写入的内容才能覆盖原来的数据。可以用fseek结合记录行起始位置来实现:
// 修改读取循环,记录每一行的起始位置 long line_start; while (day < dayEdit) { line_start = ftell(*file); // 记录当前行的起始位置 fscanf_s(*file, "%d %f %f %f", &day, &wF, &wT, &nap); printf("\n %d ", ftell(*file)); } // 找到目标行后,将指针移回该行开头 fseek(*file, line_start, SEEK_SET);
2. 文件打开模式问题
确保你打开文件时用的是"r+"模式(读写模式,允许覆盖已有内容),而不是"r"(只读)或者"w"(会直接清空文件)。如果文件是只读打开的,fprintf会直接失败。
3. 强制刷新文件缓冲区
操作系统有时会把写入的数据暂存在缓冲区,不会立刻写入磁盘。调用fflush(*file)可以强制把缓冲区内容写入文件,确保修改生效:
fprintf(*file, "%d %f %f %f\n", day, wF, wT, nap); fflush(*file); // 强制写入磁盘
4. 修复switch语句的穿透问题
你的case 4后面没有加break,会导致执行完whT = false后继续跑default分支(虽然这里没影响,但这是不良编程习惯,可能引发其他问题)。修改成:
case 4: whT = false; break; // 添加break避免穿透 default: break;
完整修改后的函数示例
void fileEdit(FILE **file) { int dayEdit = 0; int playerChoose = 0; float nap = 0.0, wF = 0.0, wT = 0.0; while (true) { int day = 0; bool whT = true; long line_start; system("CLS"); printFile(file); printf("Which day you want to edit[1 - 31, 0 to exit]: "); scanf_s("%d", &dayEdit); if (dayEdit == 0) break; // 定位到目标行并记录起始位置 while (day < dayEdit) { line_start = ftell(*file); fscanf_s(*file, "%d %f %f %f", &day, &wF, &wT, &nap); printf("\n %d ", ftell(*file)); } // 回到目标行开头准备覆盖写入 fseek(*file, line_start, SEEK_SET); while (whT) { system("CLS"); printf(" \n\n -------------------------------\n| Job Hours Managment |\n -------------------------------\n| Day | From | Till | Nap |"); printf("\n -------------------------------\n| %3d | %6.1f | %6.1f | %5.1f |", day, wF, wT, nap); printf("\n"); printf(" -------------------------------\n"); printf("\nWhat you want to edit?[1 From, 2 Till, 3 Nap, 4 Save]: "); scanf_s("%d", &playerChoose); switch (playerChoose) { case 1: printf("\nWorked from: "); scanf_s("%f", &wF); break; case 2: printf("\nWorked till: "); scanf_s("%f", &wT); break; case 3: printf("\nNap: "); scanf_s("%f", &nap); break; case 4: whT = false; break; // 修复穿透问题 default: printf("Invalid choice, try again!\n"); break; } } // 写入修改后的数据并刷新缓冲区 fprintf(*file, "%d %.1f %.1f %.1f\n", day, wF, wT, nap); // 用%.1f保持和读取一致的格式 fflush(*file); } }
额外注意事项
- 确保
printFile函数不会打乱文件指针的位置,或者在调用它之后把指针重置到正确位置,否则会影响后续的读取操作。 - 如果文件中每行的长度不一致,覆盖写入可能会破坏后面的内容。这种场景下,更稳妥的做法是把整个文件读取到内存中修改,再重新写入整个文件。
内容的提问来源于stack exchange,提问作者Yurii
相关产品推荐
相关产品推荐

