C语言中如何根据员工ID给文本文件指定行末尾添加请假类型
问题分析与解决方案
错误原因
你遇到的行首ID被覆盖问题,核心原因有三点:
- 文件指针定位错误:
fgets读取一行后,文件指针停在该行末尾(换行符之后),fseek(file, -i, SEEK_CUR)会将指针移回该行的起始位置,此时写入内容会直接覆盖行首数据,而非追加到行尾。 - 追加内容格式错误:代码未构造需求要求的
| Type of Leave: [请假类型]格式,直接写入了请假类型字符串。 - 未处理换行符:
fgets读取的行包含换行符,直接追加内容会导致格式混乱。
修正方案:临时文件法
这种方法通过创建临时文件逐行处理原内容,找到目标行修改后写入临时文件,最后替换原文件,避免直接修改原文件的覆盖风险,是最稳妥的解决方案。
修正后的代码:
#include <stdio.h> #include <string.h> #include <stdlib.h> void apply_leave() { char line[100], id[100], leave_type[100]; FILE *original_file, *temp_file; // 获取用户输入 printf("Please confirm staff ID: "); scanf("%s", id); printf("Enter leave type: "); scanf("%s", leave_type); // 打开原文件和临时文件 original_file = fopen("staff.txt", "r"); temp_file = fopen("temp_staff.txt", "w"); if (!original_file || !temp_file) { perror("Failed to open file"); return; } // 构造符合格式的追加内容 char append_content[100]; snprintf(append_content, sizeof(append_content), " | Type of Leave: %s\n", leave_type); // 逐行处理文件内容 while (fgets(line, sizeof(line), original_file)) { // 移除原行末尾的换行符 line[strcspn(line, "\n")] = '\0'; if (strstr(line, id)) { // 找到目标行,追加内容后写入临时文件 fprintf(temp_file, "%s%s", line, append_content); } else { // 其他行直接写入,补回换行符 fprintf(temp_file, "%s\n", line); } } // 关闭文件 fclose(original_file); fclose(temp_file); // 替换原文件(跨平台兼容写法) remove("staff.txt"); rename("temp_staff.txt", "staff.txt"); }
代码说明
- 临时文件处理:通过读写分离的方式,避免直接修改原文件时的内容覆盖问题。
- 格式统一:用
snprintf生成符合要求的追加内容,保证和原文件的分隔符格式一致。 - 换行符处理:用
strcspn移除原行的换行符,避免出现多余空行或格式错位。 - 文件替换:关闭文件后通过删除+重命名操作,完成原文件的更新。
可选方案:直接修改原文件(不推荐)
如果能确保追加后的行长度不会超过原文件的剩余空间,也可以直接修改原文件,但风险较高(可能覆盖下一行内容):
#include <stdio.h> #include <string.h> void apply_leave() { char line[100], id[100], leave_type[100]; FILE *file; long line_start_pos; printf("Please confirm staff ID: "); scanf("%s", id); printf("Enter leave type: "); scanf("%s", leave_type); file = fopen("staff.txt", "r+"); if (!file) { perror("Failed to open file"); return; } char append_content[100]; snprintf(append_content, sizeof(append_content), " | Type of Leave: %s", leave_type); while (fgets(line, sizeof(line), file)) { // 记录当前行的起始位置 line_start_pos = ftell(file) - strlen(line); if (strstr(line, id)) { // 移动指针到原行末尾(换行符前) fseek(file, line_start_pos + strlen(line) - 1, SEEK_SET); // 写入追加内容 fprintf(file, "%s\n", append_content); break; } } fclose(file); }
内容的提问来源于stack exchange,提问作者Tariq Mssusa
相关产品推荐
相关产品推荐

