使用fgets交替合并两个文本文件时出现跳行问题该如何解决?
错误原因
你的代码出现跳行的核心原因是单次循环中对每个输入文件都调用了两次fgets:
- 第一次调用
fgets读取到的行内容会写入目标文件 - 第二次调用
fgets仅用来判断是否到达文件尾,读取到的下一行内容没有写入就被直接丢弃,自然就会出现隔一行读一行的跳行问题
错误逻辑示例
以第一个输入文件的处理逻辑为例:
// 第一次调用fgets:读取第1行,写入目标文件 if(fgets(str1,79,pointer1)!=NULL) { fputs(str1,pointer3); } // 第二次调用fgets:读取第2行,仅判断是否为空,内容直接丢弃 if(fgets(str1,79,pointer1)==NULL) break;
第二个输入文件的处理逻辑完全相同,也存在同样的重复读取丢弃问题。
修复后的代码
将文件结束判断和读取写入逻辑合并,不需要重复调用fgets即可解决问题:
#include<stdio.h> #include<stdlib.h> #include<conio.h> // 包含getch()所需的头文件,原代码遗漏 int main() { FILE *pointer1, *pointer2, *pointer3; char source1[80],source2[80],target[80]; char str1[80],str2[80]; printf("Enter the source and source 2\n"); scanf("%s %s", source1,source2); printf("Enter the destination\n"); scanf("%s",target); pointer1 = fopen(source1,"r"); pointer2 = fopen(source2,"r"); pointer3 = fopen(target,"w"); if(pointer1 == NULL || pointer2==NULL || pointer3==NULL) { printf("Cannot open a file\n "); exit(1); } while(1) { // 读取第一个文件的行,读失败直接退出 if(fgets(str1, 80, pointer1) != NULL) { fputs(str1, pointer3); } else { break; } // 读取第二个文件的行,读失败直接退出 if(fgets(str2, 80, pointer2) != NULL) { fputs(str2, pointer3); } else { break; } } // 可选补充:如果需要把其中一个文件剩余的内容全部写完,可以添加以下逻辑 // while(fgets(str1, 80, pointer1) != NULL) fputs(str1, pointer3); // while(fgets(str2, 80, pointer2) != NULL) fputs(str2, pointer3); fclose(pointer1); fclose(pointer2); fclose(pointer3); printf("Merging completed successfully\n"); printf("Press any key to exit\n"); getch(); return 0; }
其他优化说明
fgets的第二个参数直接传入数组长度即可,函数会自动预留1个字节存储字符串结束符,不需要手动减1- 原代码引用的
<strings.h>是非标准头文件,且本场景没有用到字符串处理函数,可以直接删除 - 原代码使用
getch()但没有引入对应的<conio.h>头文件,修复后已补充 - 上述修复后的基础逻辑是任意一个文件读取结束就停止合并,如果需要读完较短文件后继续把较长文件的剩余行全部写入目标文件,可打开注释里的补充逻辑
内容的提问来源于stack exchange,提问作者Ashish Bajpai
相关产品推荐
相关产品推荐

