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

文件指针移动异常求助:无法定位至当前行末尾

问题分析与解决方案

核心问题

  1. 文件打开模式错误:你用"a"(追加模式)打开文件,这个模式的特性是所有写操作都会强制追加到文件末尾,哪怕你用fseek移动了文件指针,写入时系统会自动把指针移回文件末尾,这就是你写入的TEST出现在第二行末尾的根本原因。
  2. 行尾定位逻辑偏差:moveBelowDown函数中,当fgetc读到'\n'后,你用fseek(file, -1, SEEK_CUR)定位到换行符位置,但即使这里指针位置正确,追加模式也会让写操作失效。
  3. 未处理第二行的多余内容:你需要移除第二行末尾的TEST,这需要重新写入或修改对应行的内容。

修正步骤与代码

1. 更换文件打开模式

将打开模式从"a"改为"r+",这个模式支持读写操作,且允许通过fseek自由移动指针进行随机写入。

2. 修正行尾定位与写入逻辑

重新实现行处理逻辑,确保准确定位到第一行的有效内容末尾,并写入目标内容;同时清理第二行的多余字符。

完整修正代码

#include <stdio.h>
#include <string.h>
#include <unistd.h> // 用于ftruncate

// 清空文件内容
void clearFile(const char *filename) {
    FILE *fp = fopen(filename, "w");
    if (fp) fclose(fp);
}

// 写入键值对到文件
void writeNewVal(FILE *file, const char *key, const char *val) {
    fprintf(file, "%s: %s\n", key, val);
}

// 修改指定行内容,达成期望格式
void modifyYamlContent(FILE *file) {
    // 定位到文件开头
    fseek(file, 0, SEEK_SET);
    
    char line[100];
    long pos;
    
    // 处理第一行:将"test: "改为"test: TEST"
    if (fgets(line, sizeof(line), file)) {
        char *newline = strchr(line, '\n');
        if (newline) {
            // 计算指针位置:移动到换行符前
            pos = ftell(file) - (strlen(line) - (newline - line));
            fseek(file, pos, SEEK_SET);
            // 写入TEST并覆盖换行
            fprintf(file, "TEST\n");
        }
    }
    
    // 处理第二行:移除末尾的TEST
    if (fgets(line, sizeof(line), file)) {
        char *testStr = strstr(line, "test");
        if (testStr) {
            // 移动指针到"test"的末尾位置
            pos = ftell(file) - strlen(line) + (testStr - line) + strlen("test");
            fseek(file, pos, SEEK_SET);
            // 写入换行覆盖多余的TEST
            fprintf(file, "\n");
            // 截断文件,清除残留内容
            ftruncate(fileno(file), ftell(file));
        }
    }
}

int main() {
    clearFile("TEMP.yaml");
    FILE *yamlFile = fopen("TEMP.yaml", "r+"); // 使用r+读写模式
    
    writeNewVal(yamlFile, "test", "");
    writeNewVal(yamlFile, "mess", " test");
    
    // 刷新缓冲区,确保写入内容同步到文件,避免指针位置错误
    fflush(yamlFile);
    
    modifyYamlContent(yamlFile);
    
    fclose(yamlFile);
    return 0;
}

关键说明

  • fflush的作用:在切换读操作前必须调用,刷新写缓冲区,保证文件指针位置的准确性。
  • ftruncate的作用:处理第二行时,截断文件以清除原来末尾残留的TEST字符,因为r+模式写入不会自动删除后续内容。
  • "r+"模式注意事项:该模式要求文件已存在,所以先通过clearFile用w模式创建/清空文件,再用r+打开。

最终效果

运行后TEMP.yaml的内容会变为:

test: TEST
mess:  test

内容的提问来源于stack exchange,提问作者Jman4546

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 08:35:28