文件指针移动异常求助:无法定位至当前行末尾
问题分析与解决方案
核心问题
- 文件打开模式错误:你用
"a"(追加模式)打开文件,这个模式的特性是所有写操作都会强制追加到文件末尾,哪怕你用fseek移动了文件指针,写入时系统会自动把指针移回文件末尾,这就是你写入的TEST出现在第二行末尾的根本原因。 - 行尾定位逻辑偏差:
moveBelowDown函数中,当fgetc读到'\n'后,你用fseek(file, -1, SEEK_CUR)定位到换行符位置,但即使这里指针位置正确,追加模式也会让写操作失效。 - 未处理第二行的多余内容:你需要移除第二行末尾的
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
相关产品推荐
相关产品推荐

