第九章 文件
1.选择题
(1)C语言可以处理的文件类型是(B)。
A.文本文件和数据文件
B.文本文件和二进制文件
C.数据文件和二进制文件
D.以上都不完全
(2)调用fopen()函数,如果打开文件不成功,则函数的返回值是(C)。
A.FALSE
B.TRUE
C.NULL
D.EOF
(3)下面的变量表示文件指针变量的是(A)。
A.FILE *fp B.FILEfp
C.FILER*fp D.file*fp
FILE必须大写。
(4)若fp是指向某文件的指针,且已指到该文件的末尾,则C语言函数feof()的返回值是(B)。
A.EOF B.非0值
C.NULL D.-1
feof()函数功能是判断文件是否处于文件结束位置,若文件结束,则返回值为非0值,否则返回值为0。
(5)需要以写方式打开当前目录下一个名为file1.txt的文本文件,下列打开文件正确的选项是(A)。
A.fopen("file1.txt","w");
B.fopen("file1.txt","r");
C.fopen("file1.txt","wb");
D.fopen("file1.txt","rb");
"w"为写,"r"为读,"b"为二进制文件。A正确。
(6)执行下面程序段的输出结果是(A)。
FILE *fp;
int x=12,y=34;
fp=fopen("test.txt","w");
fprintf(fp,"%d%d",x,y);
fclose(fp);
fp=fopen("test.txt","r");
fscanf(fp,"%d",&x);
printf("%d,%d",x,y);
fclose(fp);
A.1234,34
B.12,34
C.1234
D.123434
1234被输入到test.txt文件中,后被读取到x中,此时x值为1234,y值为34。
(7)已有定义:FILE *fp;,且fp指向的文本文件内容有2000个字符,当前文件位置指针指向第1000个字符,则执行fseek(fp, 600L, 1) ;语句后,文件位置指针指向第(D)个字符。
A.400
B.600
C.1400
D.1600
600L表明向尾部移动600B,1表示起始点为当前位置。1000+600,D正确。
(8)以下叙述中正确的是(D)。
A.C语言中的文件是流式文件,因此只能顺序存取数据
B.打开一个已存在的文件并进行了写操作后,原有文件中的全部数据必定被覆盖
C.在一个程序中当对文件进行了写操作后,必须先关闭该文件然后再打开,才能读到第1个数据
D.当对文件的读/写操作完成之后,必须将文件关闭,否则可能导致数据丢失
A中,C语言中的文件是流式文件,却提供了多种函数来读写数据,并非只能顺序存取;B中,覆盖与否和写的位置相关;C中,通过fseek()、rewind()都可回到第一个数据位置。D正确。
(9)如果要将存放在双精度型数组x[10]中的10个数据写到文件指针所指向的文件中,正确的语句是(C)。
A.for(i=0;i<10;i++) fputc(x[i],fp);
B.for(i=0;i<10;i++) fputc(&x[i],fp);
C.for(i=0;i<10;i++) fwrite(&x[i],8,1,fp);
D.fwrite(fp,8,10,x);
int fputc(int char, FILE *stream)为fputc()原型,double的输入过大,A、B错误;D中未传入数组,D错误;C正确。
(10)已知有定义,FILE *fp; char str[] = "Hello!"; fp = fopen("file.dat", "wb"); 将数组str中存放的字符串写到名为file.dat的二进制文件中。需要的语句是(D)。
A.fwrite(str[0], sizeof(char), 1, fp);
B.fread(str, sizeof(char), 6, fp);
C.fwrite(fp, sizeof(char), 6, str);
D.fwrite(str, sizeof(char), 6, fp);
fwrite()的首个参数是需要输出的数据存储区的首地址,第三个参数为要输出的数据块的个数,第四个参数为指向文件的指针变量。故D正确。
2.填空题
(1)已知文本文件test.txt中的内容为:cprogram,执行下面程序段的运行结果是 cpro 。
FILE *fp;
char str[20];
if((fp=fopen("test.txt","r"))!=NULL)
fgets(str,5,fp);
printf("%s",str);
char *fgets(char *str, int n, FILE *stream);至多读取n-1个字符。代码中即"cpro"。
(2)假设已定义文件指针fp指向文本文件file.txt,则将字符变量ch输入到该文件中的方法主要有: fputc(ch,fp); 、 fwrite(&ch,1,1,fp); 、 fprintf(fp,"%c",ch); 。
(3)下面程序的功能是:从键盘输入若干整数,若输入-1则结束输入,将其中的偶数写入文本文件d3.txt中,请填空。
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int x;
FILE *fp ;
if((fp=fopen("d3.txt","w"))==NULL)
{
printf("Cannot openfile!");
exit(0);
}
scanf("%d",&x);
while( x!=-1 )
{
if(x%2==0)
fprintf(fp, "%d",x) ;
scanf("%d",&x) ;
}
fclose(fp);
}
定义并初始化文件指针fp;判断是否为-1;将偶数输出;读取下一位以循环。
(4)若文本文件file.txt中原有内容为:ABC,则运行下列程序后,文件file.txt中的内容为 ABCabc 。
#include <stdio.h>
int main(void)
{
FILE *fp;
fp=fopen("file.txt","a+");
fprintf(fp,"abc");
fclose(fp);
return 0;
}
代码对file.txt可读写的追加,追加了"abc",故内容为"ABCabc"。
(5)下列程序的运行结果为 b 。
#include <stdio.h>
int main(void)
{
FILE *fp;
int i;
char t,str[]="abcd";
fp=fopen("abc.dat","wb+");
for(i=0;i<4;i++)
fwrite(&str[i],1,1,fp);
fseek(fp,-3L,2);
fread(&t,1,1,fp);
fclose(fp);
printf("%c\n",t);
return 0;
}
在写入结束后,文件位置指针在文件末尾EOF位置,向后移动3字节,就到了b的位置。
(6)下面程序的功能是:用变量num统计文件中字符的个数,请填写完整程序。
#include<stdlib.h>
#include<stdio.h>
int main( )
{
FILE *fp;
long num=0;
if((fp=fopen("letter.dat", "r" ))==NULL)
{
printf("can’t openfile\n");
exit(0);
}
while(!feof(fp))
{
fgetc(fp) ;
num++ ;
}
printf("num=%ld\n",num-1);
fclose(fp);
return 0;
}
统计文件中字符的个数,故只读即可,"r";获取字符;累加数量到num。
(7)下面程序将一组数据写入file.dat文件中,请填写完整程序。
#include<stdio.h>
#include<stdlib.h>
int main( )
{ char dt[9] ={'1', '2', '3','4', '5', '6', '7', '8', '9'};
FILE *fp;
fp = fopen("file.dat","wb") ;
if ( fp ==NULL )
{
printf("file can’t open! ");
exit(0);
}
fwrite( dt,1,9,fp );
fclose( fp);
return 0;
}
fp需要初始化为file.dat的文件指针,需要写入功能,文件为二进制文件;需要将数组的九个字符写入到文件。
(8)下列程序的运行结果为 24, 0 。
#include<stdio.h>
int main(void)
{
FILE *fp;
int i, k=0,n=0;
fp=fopen("d1.dat","w");
for(i=1;i<4;i++)
fprintf(fp,"%d",++i);
fclose(fp);
fp=fopen("d1.dat","r");
fscanf(fp,"%d",&k);
printf("%d, %d\n",k,n);
fclose(fp);
return 0;
}
在for循环中,每次执行中i值加1,执行后i值加1,故实际只执行了两次,写入了2、4,故k值为24,n值始终为0。
(9)下列程序的运行结果为 sum=-26.4 。
#include<stdlib.h>
#include<stdio.h>
int main(void)
{
FILE *fp;
float sum=0.0,x;
int i;
float y[4]={-12.1,13.2,-14.3,15.4};
if((fp=fopen("data1.dat","wb"))==NULL)
exit(0);
for(i=0; i<4; i++)
fwrite(&y[i],4,1,fp);
fclose(fp);
if((fp=fopen("data1.dat","rb"))==NULL)
exit(0);
for(i=0;i<4;i++,i++)
{
fread(&x,4,1,fp);
sum+=x;
}
printf("sum=%.1f\n",sum);
fclose(fp);
return 0;
}
由于for(i=0;i<4;i++,i++)中,进行了两次加1,fread()只操作了y[0],y[2]两数,即-12.1和-14.3,输出为sum=-26.4。(该题可能与原书不一致)
(10)下列程序的运行结果为 11 22 77 88 99 100 。
#include <stdio.h>
int main(void)
{
FILE *fp;
int a[10] = {11,22,33,44,55,66,77,88,99,100 };
int b[6], i;
fp = fopen("test.dat", "wb" );
fwrite( a, sizeof(int), 10,fp );
fclose( fp );
fp = fopen("test.dat", "rb" );
fread( b, sizeof(int), 6,fp );
fread( b+2, sizeof(int), 4,fp );
fclose( fp );
for ( i = 0; i < 6; i++)
printf( "%d ", b[i] );
return 0;
}
fread( b, sizeof(int), 6,fp );将数组a的六个元素读入到b[0]到b[5]的位置,而此时文件位置指针指到了a[6]处。fread( b+2, sizeof(int), 4,fp );将a[6]到a[9]读入到b[2]到b[5]的位置。故为a[0]、a[1]、a[6]、a[7]、a[8]、a[9]。
3.编程题
(1)假设文本文件g1.txt中有若干字符,编写程序将g1.txt中的内容复制到g2.txt中,并统计文件中字母、数字和其他字符出现的个数,显示在屏幕上。
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
FILE* fp1, * fp2;
char ch;
int n1, n2, n3;
n1 = n2 = n3 = 0;
if ((fp1 = fopen("g1.txt", "r")) == NULL)
{
printf("Cannot open this file.\n");
exit(0);
}
if ((fp2 = fopen("g2.txt", "w")) == NULL)
{
printf("Cannot open this file.\n");
exit(0);
}
while (!feof(fp1))
{
ch = getc(fp1);
putc(ch, fp2);
if (ch >= 'A' && ch <= 'Z' || ch >= 'a' && ch <= 'z')
n1++;
else if (ch >= '0' && ch <= '9')
n2++;
else n3++;
}
rewind(fp1);
while (!feof(fp1))
putchar(getc(fp1));
fclose(fp1);
fclose(fp2);
printf("\nletter=%d,digit=%d,others=%d\n", n1, n2, n3);
return 0;
}
(2)从键盘输入10个浮点数,以二进制形式存入文件g3.dat中。再从文件中读出数据显示在屏幕上。
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
FILE* fp;
int i;
double a[10], b[10];
if ((fp = fopen("g3.dat", "wb+")) == NULL)
{
printf("file can not open!\n");
exit(0);
}
printf("Input data:\n");
for (i = 0; i < 10; i++)
scanf("%lf", &a[i]);
for (i = 0; i < 10; i++)
fwrite(a + i, sizeof(double), 1, fp);
printf("\n");
rewind(fp);
fread(b, sizeof(double), 10, fp);
printf("Output data:\n");
for (i = 0; i < 10; i++)
printf("%.1f\n", b[i]);
fclose(fp);
return 0;
}
(3)假设文件g4.txt中已经存放了一组整数,编程统计并输出文件中正数、负数和零的个数,并将统计结果写到g4.txt文件的最后。
#include<stdio.h>
#include<stdlib.h>
int main(void)
{
int p = 0, n = 0, z = 0, temp;
FILE* fp;
if ((fp = fopen("g4.txt", "r")) == NULL)
{
printf("Cannot open this file.\n");
exit(0);
}
else
fscanf(fp, "%d", &temp);
while (!feof(fp))
{
if (temp > 0) p++;
else if (temp < 0) n++;
else z++;
fscanf(fp, "%d", &temp);
}
fclose(fp);
printf("positive:%d,negtive:%d,zero:%d\n", p, n, z);
fp = fopen("g4.txt", "a");
fprintf(fp, "positive:%d,negtive:%d,zero:%d\n", p, n, z);
return 0;
}
(4)有3个学生,每个学生有两门课的成绩,定义结构体类型,编程:从键盘输入数据(包括学号、姓名和2门课成绩),计算出每个学生的总分,将原有数据和计算出的总分存放在磁盘文件student中。
#include<stdio.h>
#include<stdlib.h>
#define N 3
struct stu
{
int no;
char name[16];
float mark[2];
float sum;
}st[N];
int main(void)
{
FILE* fp;
int i, j;
if ((fp = fopen("student.dat", "wb")) == NULL)
{
printf("Cannot open this file.\n");
exit(0);
}
for (i = 0; i < N; i++)
{
printf("请输入第 %d 个学生的学号、姓名 ", i + 1);
scanf("%d", &st[i].no);
gets(st[i].name);
printf("请输入第 %d 个学生的两门课的成绩 ", i + 1);
scanf("%f%f", &st[i].mark[0], &st[i].mark[1]);
st[i].sum = st[i].mark[0] + st[i].mark[1];
fwrite(&st[i], sizeof(struct stu), 1, fp);
}
fclose(fp);
if ((fp = fopen("student.dat", "rb")) == NULL)
{
printf("Cannot open this file.\n");
exit(0);
}
for (i = 0; i < N; i++)
fread(&st[i], sizeof(struct stu), 1, fp);
printf("\n");
for (i = 0; i < N; i++) //输出每个人的学号、姓名、2门课分数与总分
{
printf("%5d%-6s", st[i].no, st[i].name);
for (j = 0; j < 2; j++)
printf("%8.1f", st[i].mark[j]);
printf("%10.2f\n", st[i].sum);
}
fclose(fp);
return 0;
}
如有错误不足之处,恳请批评指正。
题目来源:C程序设计教程与实验(第3版) 吉顺如主编
答案参照微信公众号:程序设计及信息技术学习平台