11 阅读下列程序,写出程序的主要功能。
#include”stdio.h”
main()
{ FILE *fp;
char ch;
long count1=0, count2=0;
if((fp=fopen("p1.c","r"))==NULL) exit(0);
while(!feof(fp))
{ ch=fgetc(fp);
if(ch=='{')countl++;
if(ch=='}')count2++;
}
if( count1==count2)
printf("YES!\n");
else
printf("ERROE!\n”);
fclose(fp);
}
【分析】本程序的关键是while语句,从控制该循环的条件(不是文件尾)来看,这个当型循环结构是依次处理文件中的所有数据的标准程序段。分析该循环语句的循环体,可以看出是分别统计文件中的字符'{'和'}'的数目,并分别存放在变量count1和count2中。退出循环后,比较这两个统计变量的值,如果相等,则输出“YES!”,如果不相等,则输出“ERROR!”。由此不难总结出本程序的基本功能。
【答案】如果文件p1.c中的“{”和“}”的数目不相等,则输出“ERROR!”;否则输出“YES!”。实际上,本程序是检查C语言源程序清单中的花括号是否配对。
12 假定名为“data1.dat”的二进制数据文件中依次存放了下列4个单精度实数:
-12.1、12.2、-12.3、12.4
阅读下列程序,写出运行该程序后的输出结果。
#include"stdio.h"
main()
{ FILE *fp;
float sum=0.0,x;
int i;
if((fp=fopen("data1.dat","rb"))==NULL) exit(0);
for(i=0;i<4;i++,i++)
{ fread(&x,4,l,fp);
sum+=x;
}
printf("%f\n",sum);
fclose( fp);
}
【分析】本程序的前4条语句比较简单,首先定义文件型指针;定义单精度变量sum和x,并给sum赋初值 0.0;定义整型变量i;然后打开datal.dat的二进制文件用于只读。接下来的for循环是关键,我们可以用记录变量值的方法记录运行结果,记录如下:
循环前: sum=0.0, i=0,循环控制条件i<4成立,开始循环。
第1次循环:从文件中读取4个字节的数据(单精度实数-12.1)存入x,加到变量sum中,sum值为0.0 +(-12.1);执行i++,i++,i为 2,循环控制条件i<4成立,继续循环。
第2次循环:从文件中读取4个字节的数据(单精度实数12.2)存入x,加到变量 sum中,sum值为一 12.1+12.2,结果是 0.1;执行 i++,i++,i为 4,循环控制条件 i< 4不成立,退出循环。最终输出的就是变量sum中的值,结果为0.1。
【答案】0.1
【说明】建立本程序要求读取数据的、名为“data1.dat”的二进制数据文件,可以使用下列程序:
#include”stdio.h”
main()
{ FILE *fp;
float x[4]={-12.1,12.2,-12.3,12.4 };
int i;
if((fp= fopen(”data1. dat”,”wb”))== NULL) exit(0);
for( i= 0; i< 4; i++)
fwrite( &x「 i」, 4, 1, fp);
fclose( fp);
}
13 编程序完成下列功能:从键盘读取40个人的姓名,每个姓名是一个字符串(长度要求<=20),存入名为“sname.txt”的文本文件中。
【说明】从文件中读取字符串时,一般要求以字符数目或者读到回车换行符为一个字符串结束(参看 fgets()的功能)。为了将来能正确读取本程序建立的文件中的字符串,要求从键盘上读取字符串后,在最后一个有效字符的后面插入一个回车换行符,然后再写入文件。
【分析】定义文件型指针,打开名为“sname.txt”文本文件用于只写操作。再设计一个次数为40的单重次数型循环,输入40个字符串并插入“回车换行符”写入指定的文件中。
【答案】 #include"stdio.h"
main()
{ FILE *fp;
int i;
char s[21];
if((fp=fopen("sname.txt","w"))==NULL) exit(0);
for(i=0;i<40;i++)
{ scanf<("%s",s);
fputs(s,fp);
fputc('\n',fp);
}
fclose(fp);
}
14 编程序完成下列要求:从键盘上输入某个姓名(字符串,长度<=20),在上一题(第13题)中建立的名为“sname.txt”的文本文件中查找,找到则输出“yes!”,找不到则输出 “no!”。
【说明】 因为建立的sname文本文件中的字符串是含有回车换行符的,所以进行查找时的姓名字符串也需要插入一个回车换行符。
【分析】 定义文件型指针,并且打开名为“sname.txt”文本文件,用于只读操作。输入待查的字符串,插入回车换行符。设置标记变量值为0,表示没有查到。再设计一个当型循环结构,控制循环的条件是“不是文件尾”;在循环体中,从文件中读取一个字符串,和待查字符串比较。两个字符串相等,则置标记变量为1(表示查到),并且强迫退出循环;两个字符串不相等,则继续循环。退出循环后,按照标记变量的值进行输出。
【答案】 #include"stdio.h"
#Include"string.h"
main()
{ FILE *fp;
char name[22],s[22];
int flag,i;
if((fp=fopen("sname.txt","r"))==NULL) exit(0);
scanf("%s",name);
for(i=0;name[i]!='\0';i++);/*找到字符串结束标记*/
name[i]='\n';/*字符串中插入一个回车换行符*/
name[i+1]='\0';/*补充一个字符串结束标记*/
flag= 0;
while(!feof(fp))
{ fgets(s,21,fp);
if(strcmp(s,name)==0)
{ flag=1;
break;
}
}
if(flag==1)
printf("yes!\n");
else
printf("no!\n");
fclose(fp);
}
15 按照下列要求,编写一个函数。
函数名: file_err
参数:fpp,一个文件型指针
功能:测试fpp所指向的文件最近一次操作是否出现错误。
返回值:如果出现错误,则返回1;没有出现错误,则返回0。
【分析】在函数体中利用系统函数 ferroe()来测试参数“fpp”所指向的文件最近一次操作是否出错,依据ferror()函数的返回值(有错返回非0值。无错返回0值)来获得本函数的返回值进行返回。
【答案】 int file_err(fpp)
FILE *fpp;
{ int k;
k=ferror(fpp);
if(k)
return(1);
else
return(0);
}