You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.29 00:02:35