编程语言
首页 > 编程语言> > 浙大版《C语言程序设计》第四版(何钦铭颜晖) 第12章 文件 课后习题答案

浙大版《C语言程序设计》第四版(何钦铭颜晖) 第12章 文件 课后习题答案

作者:互联网

你也可以上程序咖(https://meta.chengxuka.com),打开大学幕题板块,不但有答案,讲解,还可以在线答题。

WX20220412-135428@2x

一、选择题

1.以下语句的输出结果是( )。

printf("%d,%d,%d", NULL, '\0', EOF);

A.0,0,1

B.0,0,-1

C. NULL, ,EOF

D. 1,0, EOF

答:B

解析:

NULL等于0
'\0'也是等于0
EOF等于-1

2.缓冲文件系统的文件缓冲区位于( )。

A.磁盘缓冲区中

B.磁盘文件中

C.内存数据区中

D.程序文件中

答:C

解析:

文件缓冲区是用以暂时存放读写期间的文件数据而在内存区预留的一定空间

3.定义 FILE *fp; 则文件指针 fp 指向的是( )。

A.文件在磁盘上的读写位置

B.文件在缓冲区上的读写位置

C.整个磁盘文件

D.文件类型结构

答:D

解析:

语句 FILE *fp; ,定义了一个 FILE 结构指针, FILE 是 C 语言为了具体实现对文件的操作而定义的一个包含文件操作相关信息的结构类型。

4.若以 “a+” 方式打开一个已存在的文件, 则以下叙述正确的是( )。

A.文件打开时,原有文件内容不被删除,位置指针移到文件末尾,可执行添加和读操作

B. 文件打开时,原有文件内容不被删除,位置指针移到文件开头,可执行重写和读操作

C.文件打开时,原有文件内容被删除,只可执行写操作

D.以上各种说法都不正确

答:A

解析:

"a+" 的打开模式,打开文本文件进行读/写/追加。

5.以下可作为函数 fopen() 中第一个参数的正确格式是( )。

A. C: user\text. txt

B. c: \user\text. txt

C. "e:\user\ text. txt"

D. "c:\\user\\text.txt"

答:D

解析:

函数 fopen 的第一个参数是指要打开的文件名的字符串,所以选项 A、B 是错误的。文件路径分隔符 \ 必须使用转义字符,即 \\,所以选项 C 也是错误的。选项 D 是正确的。

二、填空题

1.文件的三大特征是( )、数据长度不定和数据按顺序存取。

答:数据长久保存

解析:

文件是保存在外在存储器上的一组数据的有序集合。文件的特点是数据长久保存,数据长度不定,数据按顺序存取。

2.根据数据存储的编码形式,C 语言中处理的数据文件通常为( )文件和( )文件两种。

答:

文本文件

二进制人间

解析:

在 C 语言中,按照存储的编码形式,数据文件可以分为文本文件和二进制文件两种。文本文件是以字符 ASCII 码值进行存储与编码的文件,其文件的内容就是字符。二进制文件是存储二进制数据的文件。

3.判断文件指针是否已经到了文件尾部的函数是( )。

答:feof()

解析:

feof() ,用于判断 fp 指针是否已经到文件末尾,即读文件是否读到了文件结束的位置。其调用格式为:feof(fp); 该函数成功返回 1 表示已经到了文件结束位置,0 表示文件未结束。

4.统计文本文件的字符数量。统计文本文件 "letter.txt" 中字符的个数。请填空。

#include <stdio.h>
int main()
{
	FILE *fp;
	int count = 0;
	fp = fopen("letter.txt", _________);
	while (!feof(fp))
	{
		_________;
		count++;
	}
	printf("count=%d\n", count);
	fclose(fp);
	return 0;
}

答:

"r"

fgetc(fp)

解析:

第一个空,打开文件的模式,因为只是读取,所以填 "r" 就可以。

第二个空,就是逐个读取字符。

5.以下程序段实现的功能是( )。

	char infile[10], outfile[10];
	FILE *fpa, *fpb;
	gets(infile);
	gets(outfile);
	fpa = fopen(infile, "r");
	fpb = fopen(outfile, "w");
	while (!feof(fpa))
	{

		fputc(fgetc(fpa), fpb);
	}
	fclose(fpa);
	fclose(fpb);

答:将文件名为键盘输入的infile表示的文件内容复制到文件名为键盘输入的outfile变量表示的文件中

解析:

这里只读模式打开了infile文件,只写模式打开了outfile,然后循环读取infile文件中的每个字符,写入到outfile文件中。

三、程序设计题

题目1:统计文本文件中各类字符个数:分别统计一个文本文件中字母,数字及其他字符的个数。试编写相应程序。

答案代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	// 习题(12.3.1)
	/*
	统计文本文件中各类字符个数:分别统计一个文本文件中字母,数字及其他字符的个数。

	*/

	char ch;
	char *path = "data1.txt";
	FILE *fp = fopen(path, "r");
	if (!fp)
	{
		printf("file open error\n");
		exit(0);
	}

	int letter = 0, digit = 0, other = 0;

	while ((ch = fgetc(fp)) != EOF) // EOF 表示到达末尾
	{
		if ((ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z'))

			letter++;
		else if (ch >= '0' && ch <= '9')
			digit++;
		else
			other++;
	}
	printf("字母:%d,数字:%d,其他:%d\n", letter, digit, other);

	fclose(fp);
	return 0;
}

运行结果:

WX20220419-145653@2x

所读文件内容如下:

WX20220419-145717@2x

题目2:将实数写入文件:从键盘输入若干实数(以特殊数值-1结束),分别写到一个文本文件中。试编写相应程序。

答案代码:

#include <stdio.h>
#include "stdlib.h"
int main()
{
	// 习题(12.3.2)
	/*
	将实数写入文件:从键盘输入若干实数(以特殊数值-1结束),分别写到一个文本文件中。

	*/

	FILE *fp;
	float num = 0;

	fp = fopen("data2.txt", "w+");
	if (!fp)
	{
		printf("file open error\n");
		exit(0);
	}
	while (scanf("%f", &num), num != -1)
	{
		fprintf(fp, "%f\n", num);
	}
	fclose(fp);

	return 0;
}

运行结果:

WX20220419-150649@2x

写入目标文件:

WX20220419-150704@2x

题目3:比较两个文本文件是否相等:比较两个文本文件的内容是否相同,并输出两个文件中第一次出现不同字符内容的行号及列值。试编写相应程序。

答案代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	// 习题(12.3.3)
	/*
	比较两个文本文件是否相等:比较两个文本文件的内容是否相同,并输出两个文件中第一次出现不同字符内容的行号及列值。

	*/

	FILE *fp1, *fp2;
	int array1 = 1, row1 = 1, array2 = 1, row2 = 1;
	char ch1, ch2;
	// data3_1 与 data3_2 都是与当前程序在同一目录下的文件
	fp1 = fopen("data3_1.txt", "r");
	fp2 = fopen("data3_2.txt", "r");
	if (!fp1 || !fp2)
	{
		printf("file open error\n");
		exit(0);
	}

	while (!feof(fp1) || !feof(fp2))
	{
		ch1 = fgetc(fp1);
		ch2 = fgetc(fp2);
		if (ch1 == '\n')
		{
			row1++;
			array1 = 1;
		}
		if (ch2 == '\n')
		{
			row2++;
			array2 = 1;
		}
		if (ch1 == EOF || ch2 == EOF)
			break;
		if (ch1 != ch2)
		{
			printf("data3_1\t行号:%d 列号:%d\n", row1, array1);
			printf("data3_2\t行号:%d 列号:%d\n", row2, array2);
			break;
		}
		else
		{
			array1++;
			array2++;
			printf("读到字符:%c\n", ch1);
		}
	}
	if (ch1 == EOF && ch2 != EOF)
		printf("data3_2 文件已经到达末尾");
	if (ch2 == EOF && ch1 != EOF)
		printf("data3_1 文件已经到达末尾");
	if (ch1 == EOF && ch2 == EOF)
		printf("两个文件完全相同!");
	fclose(fp1);
	fclose(fp2);

	return 0;
}

两个文件的内容相同:

WX20220419-152032@2x

运行结果:

WX20220419-152057@2x

两个文件的内容不同:

WX20220419-152136@2x

运行结果:

WX20220419-152203@2x

题目4:将文件中的数据求和并写入文本文件尾:文件 Int _Data.dat 中存放了若干整数,将文件中所有数据相加,并把累加和写入该文件的最后。试编写相应程序。

答案代码:

#include <stdio.h>
#include <stdlib.h>
int main()
{
	// 习题(12.3.4)
	/*
	将文件中的数据求和并写入文本文件尾:文件Int _Data. dat 中存放了若干整数,将文件中所有数据相加,并把累加和写入该文件的最后。

	*/
	FILE *fp;
	int n, sum = 0;
	fp = fopen("Int _Data.dat", "rb+");
	if (!fp)
	{
		printf("file open error\n");
		exit(0);
	}
	// 读取
	while (fscanf(fp, "%d", &n) != EOF)
		sum += n;
	printf("sum = %d\n", sum);
	fprintf(fp, "\n%d", sum);
	fclose(fp);
	return 0;
}

Int _Data.dat 文件中的内容:

WX20220419-160047@2x

运行结果:

WX20220419-160103@2x

写入计算结果后,Int _Data.dat 文件中的内容:

WX20220419-160114@2x

题目5:输出含 for 的行:将文本文件 test.txt 中所有包含字符串 “for” 的行输出。试编写相应程序。

答案代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 80

void Findfor(char *ch);
int main()
{
	// 习题(12.3.5)
	/*
	输出含 for 的行:将文本文件 test.txt 中所有包含字符串  “for”  的行输出。

	*/

	FILE *fp;
	char ch[N];
	fp = fopen("test.txt", "r");
	while (!feof(fp))
	{
		fgets(ch, N, fp);
		Findfor(ch);
	}
	fclose(fp);
	return 0;
}

void Findfor(char *ch)
{
	int i = 0;
	for (i = 0; i < strlen(ch); i++)
	{
		if (ch[i] == 'f' && ch[i + 1] == 'o' && ch[i + 2] == 'r')
			printf("This row have for:%s\n", ch);
	}
}

test.txt 文件内容如下:

WX20220419-160701@2x

运行结果:

WX20220419-160727@2x

题目6:删除文件中的注释:将 C 语言源程序( hello.c)文件中的所有注释去掉后存入另一个文件(new_ hello.c)。 试编写相应程序。

答案代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
	// 习题(12.3.6)
	/*
	删除文件中的注释:将 C 语言源程序( hello.c)文件中的所有注释去掉后存入另一个文件(new_ hello.c)。

	*/

	FILE *fp1, *fp2;
	char ch;
	char comment[2];
	/*打开读出数据的文件*/
	if ((fp1 = fopen("hello.c", "r")) == NULL)
	{
		printf("File open error!\n");
		exit(0);
	}
	/*打开写入数据的文件*/
	if ((fp2 = fopen("new_hello.c", "w")) == NULL)
	{
		printf("File open error!\n");
		exit(0);
	}
	/*对文件1中的字符进行处理*/
	while (!feof(fp1))
	{
		ch = fgetc(fp1);
		if (ch == EOF)
			continue;
		if (ch == '/')
		{
			ch = fgetc(fp1);
			//单行注释 ,遇到换行符结束,结束后需输出换行符
			if (ch == '/')
			{
				while (ch != '\n' && ch != EOF)
				{
					ch = fgetc(fp1);
				}
				fputc('\n', fp2);
			}
			/*跨行注释,遇到结束符结束,每次读入两个字符进行比较,若不是则退回一个字符,继续比较*/
			else if (ch == '*')
			{
				fgets(comment, 3, fp1);
				while (strstr(comment, "*/") == NULL)
				{
					fseek(fp1, -1L, SEEK_CUR);
					fgets(comment, 3, fp1);
				}
			}
			//不是注释符,只是单纯的'/'符号,则退回两个字符,读写'/'
			else
			{
				fseek(fp1, -2L, SEEK_CUR);
				ch = fgetc(fp1);
				fputc(ch, fp2);
			}
		}
		else
		{
			fputc(ch, fp2);
		}
	}
	//关闭文件
	if (fclose(fp1))
	{
		printf("Can not close the file! \n");
		exit(0);
	}
	//关闭文件
	if (fclose(fp2))
	{
		printf("Can not close the file! \n");
		exit(0);
	}
	printf("处理结束\n");

	return 0;
}

运行结果:

WX20220419-161458@2x

hello.c 文件和 new_ hello.c 文件对比:

WX20220419-161407@2x

题目7:(选做)账户余额管理:创建一个随机文件,用来存储银行账户和余额信息,程序要求能够查询某个账户的余额,当客户发生交易额时(正表示存入,负表示取出)能够更新余额。账户信息包括账号、账号名和余额三个数据项。试编写相应程序。

文件部分内容如下:



AcctNo AcctName Balance
1 zhangsan 1 000. 00
2 lisi 1 300. 00
3 wangwu - 100. 00
……

答案代码:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

long size;
struct account
{
	char no[10];
	char acctname[50];
	double balance;
};

FILE *openfile(char *openmode);
double userbalance(FILE *fp, char *name);
void pay(FILE *fp, char *name, double count);
int main()
{
	// 习题(12.3.7)
	/*
	选做)账户余额管理:创建一个随机文件,用来存储银行账户和余额信息,程序要求能够查询某个账户的余额,当客户发生交易额时(正表示存入,负表示取出)能够更新余额。账户信息包括账号、账号名和余额三个数据项。

	*/

	FILE *fp;
	int choice;
	char name[50];
	double balance;
	double count;

	while (1)
	{
		printf("请输入选择类型\n");
		printf("1.查账户余额\n");
		printf("2.账户交易\n");
		printf("退出按其她\n");
		scanf("%d", &choice);
		switch (choice)
		{
		case 1:
		{
			printf("输入名字:");
			scanf("%s", name);
			fp = openfile("r+");
			balance = userbalance(fp, name);
			printf("%s, %.2lf\n", name, balance);

			break;
		}
		case 2:
		{
			printf("输入名字:");
			scanf("%s", name);
			fp = openfile("r+");
			printf("输入交易金额:");
			scanf("%lf", &count);
			pay(fp, name, count);
			break;
		}
		default:
			exit(0);
			break;
		}
	}
	return 0;
}
// 打开文件
FILE *openfile(char *openmode)
{
	FILE *fp;
	if ((fp = fopen("accout.dat", openmode)) == NULL)
	{
		printf("File open error!\n");
		exit(0);
	}
	return fp;
}

// 用户余额
double userbalance(FILE *fp, char *name)
{
	struct account user;
	double balance;
	fseek(fp, 0L, SEEK_SET);
	while (!feof(fp))
	{
		fscanf(fp, "%s %s %lf", user.no, user.acctname, &user.balance);
		if (strcmp(user.acctname, name) == 0)
		{
			balance = user.balance;
			break;
		}
	}
	// fclose(fp);
	return balance;
}

// 交易
void pay(FILE *fp, char *name, double count)
{
	FILE *fpout;
	struct account user;
	double balance;
	balance = userbalance(fp, name);
	balance = balance + count;
	fseek(fp, 0L, SEEK_SET);
	fpout = fopen("temp.dat", "w");
	int no = 0;
	int res = 1;
	while (1)
	{
		res = feof(fp);
		if (res != 0)
		{
			break;
		}

		fscanf(fp, "%s %s %lf\n", user.no, user.acctname, &user.balance); //读入
		// printf("%s %s %lf\n", user.no, user.acctname, user.balance);
		if (strcmp(user.acctname, name) == 0)
		{
			user.balance = balance;
			// printf("if---%s %s %lf\n", user.no, user.acctname, user.balance);
			fprintf(fpout, "%s %s %.2lf\n", user.no, user.acctname, user.balance);
		}
		else
		{
			// printf("else---%s %s %lf\n", user.no, user.acctname, user.balance);
			fprintf(fpout, "%s %s %.2lf\n", user.no, user.acctname, user.balance);
		}
	}

	fclose(fpout);
	fclose(fp);
	unlink("accout.dat");
	rename("temp.dat", "accout.dat");
}

accout.dat 文件内容:

WX20220419-173003@2x

运行结果:

WX20220419-183837@2x

accout.dat 更改后:

WX20220419-183925@2x

标签:颜晖,fp,ch,FILE,文件,user,课后,printf,习题
来源: https://www.cnblogs.com/hanru/p/16261183.html