我一直在解决这个问题:
从 2 个文件中选择合并行并打印结果的 C 程序
这是我写的代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp;
FILE *fp1;
FILE *fp2;
fp=fopen ("sample4.txt","r");
fp1=fopen ("sample3.txt","r");
fp2= fopen ("output.txt","w");
char a[100];
char b[100];
while (fgets(a,100,fp1)!=NULL||fgets (b,100,fp)!=NULL){
printf("%s",a);
printf ("%s",b);
}
return 0;
}
但是我没有得到想要的输出。有人能解释一下原因吗?
PS:还有一个问题要求: 如果一个文件的行数少于另一个文件,则应简单地打印较大文件中的其余行。
答案 0 :(得分:2)
但是我没有得到想要的输出。有人能解释一下原因吗?
当fgets(a,100,fp1)!=NULL||fgets (b,100,fp)!=NULL
的左侧为真(由于读取成功)时,fgets()
不会评估第二个 ||
。
还有一个问题要求:如果一个文件的行数少于另一个文件,则应该简单地打印较大文件中的剩余行。
与其尝试从已经返回 NULL
的流中重新读取,不如考虑每个流的标志:
// OP may want to stop before here if an fopen() failed.
bool ok_a = fp1; // Did file open OK?
bool ok_b = fp;
char a[100];
char b[100];
while (ok_a || ok_b) {
// OK to read and then set the flag per the read result.
if (ok_a && (ok_a = fgets(a, sizeof a, fp1)) {
printf("%s",a);
}
if (ok_b && (ok_b = fgets(b, sizeof b, fp)) { // ***
printf("%s",b);
}
}
// Optional
printf("a: EOF:%d, Error:%d\n", feof(fp1), ferror(fp1));
printf("b: EOF:%d, Error:%d\n", feof(fp) , ferror(fp));
// Good to close the files
// A fclose() should NOT get called if the FILE * pointer is NULL.
if (fp) fclose(fp);
if (fp1) fclose(fp1);
if (fp2) fclose(fp2);
OP 可能需要额外的代码来处理 fgets()
的结果由于是长行、嵌入的 空字符 或最后一行。
*** 请注意,不需要第二个缓冲区,可以重复使用 '\n'
。
答案 1 :(得分:0)
问题出在 ||
(或)在 while
循环中。如果第一个 fgets
成功,则不执行第二个。试试这个:
char * r1, * r2;
do
{
r1 = fgets(a,100,fp1);
r2 = fgets(b,100,fp);
if (r1)
printf("%s",a);
if (r2)
printf ("%s",b);
} while ( r1 != NULL || r2 != NULL );
另一种“hack”方法是使用您的代码并仅修改 while
行(添加 #include <stdint.h>
):
while ( ( (uintptr_t)fgets(a,100,fp1) | (uintptr_t)fgets (b,100,fp) ) != 0 )