问题描述
我一直在解决这个问题:
编写一个程序,将两个文件中的行交替合并,并将结果写入新文件。如果一个文件的行数少于另一个文件,则应将较大文件中剩余的行简单地复制到目标文件中。
这是我的代码:
#include <stdio.h>
#include <stdlib.h>
int main(){
FILE *fp;
FILE *fp1;
FILE *fp2;
fp=fopen("sample3.txt","r");
fp1=fopen("sample4.txt","r");
fp2=fopen ("output.txt","w");
char a[100];
char b[100];
int *p;
int *c;
while (1){
if (p=fgets(a,100,fp)!=NULL){
fputs (a,fp2);
}
if (c=fgets(b,fp1)!=NULL){
fputs (b,fp2);
}
if (c==NULL && p==NULL){
break;
}
}
return 0;
}
虽然 output.txt 文件包含来自这两个文件的字符串,但编译器显示 [警告] 赋值使指针从整数而不进行以下两行强制转换:
if (c=fgets(b,fp1)!=NULL)
和
if (p=fgets(a,fp)!=NULL)
有人可以帮忙吗?
解决方法
表达式:
c = fgets(b,100,fp1) != NULL
相当于:
c = (fgets(b,fp1) != NULL)
因为 !=
的优先级高于 =
,因此这会将比较中的布尔整数转换为指针。您应该使用显式括号来解决此问题:
(c = fgets(b,fp1)) != NULL
这将对 c
进行赋值(因为括号赋予该操作更高的优先级)然后将该值与 NULL
进行比较。
两个问题:
-
p
和c
是指向错误类型的指针(int
而不是char
) - If 语句是错误的。它将逻辑表达式的结果分配给指针。逻辑表达式的结果可以是
1
或0
,它们是整数,因此警告。您需要先分配指针,然后进行比较。
char *p;
char *c;
while (1){
if ((p=fgets(a,fp))!=NULL){
fputs (a,fp2);
}
if ((c=fgets(b,fp1))!=NULL){
,
没有任何括号,你正在这样做:
if (c= (fgets(b,fp1)!=NULL) )
比较的结果是 int
,这就是您分配给 char* c
的结果。您可以打印它,您会看到它是 1
(当 fgets()
返回的不是 NULL
时)或 0
(如果 fgets()
返回 {{ 1}}).
您想要的是以下内容:
NULL
甚至更好(直到您更精通组合多个语句)
if ( (c=fgets(b,fp1)!=NULL) )
第二行也必须这样做。此外,将 c= fgets(b,fp1);
if ( c!=NULL )
和 p
从 c
更改为 int*
。
以下建议代码:
- 干净地编译
- 允许超过 99 个字符的行
- 检查所有 I/O 错误
- 报告
stderr
上的 I/O 错误 - 执行所需的功能
- 给出“神奇”的数字,比如 100,有意义的名字
- 可以很容易地“调整”,因此一旦遇到 EOF,就不再读取该文件
现在,建议的代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_LINE_LEN 100
int main( void )
{
FILE *fp = fopen( "sample3.txt","r" );
if( ! fp )
{
perror( "fopen to read: sample3.txt failed" );
exit( EXIT_FAILURE );
}
FILE *fp1 = fopen( "sample4.txt","r" );
if( ! fp1 )
{
perror( "fopen to read: sample4.txt failed" );
fclose( fp );
exit( EXIT_FAILURE );
}
FILE *fp2 = fopen ( "output.txt","w" );
if( ! fp2 )
{
perror( "fopen to write: output.txt failed" );
fclose( fp );
fclose( fp1 );
exit( EXIT_FAILURE );
}
char buffer[ MAX_LINE_LEN ];
char *ap = NULL;
char *bp = NULL;
do
{
do
{
if ( (ap = fgets(buffer,sizeof( buffer ),fp) ) != NULL )
{ // then read successful
if( EOF == fputs ( buffer,fp2 ) )
{ // then,write failed
perror( "fputs failed" );
break;
}
}
else
{ // else,read failed
perror( "fgets failed" );
break;
}
// while end of line not found
} while( strchr( buffer,'\n' ) == NULL );
do
{
if ( (bp = fgets(buffer,fp1) ) != NULL )
{
if( EOF == fputs ( buffer,fp2 ) )
{
perror( "fputs failed" );
break;
}
}
else
{
perror( "fgets failed" );
break;
} while( strchr( buffer,'\n' ) == NULL );
// while more to read
} while( ap || bp );
fclose( fp );
fclose( fp1 );
fclose( fp2 );
return 0;
}