明解C语言入门篇_第13章_文件处理

前言

本文为业余学习《明解C语言入门篇》的记录,包含代码清单和练习题。
开始学习时间:2022年8月21日
+++++++++++++++++++++++++++++++
第1章 初识C语言
第2章 运算和数据类型
第3章 分支结构程序
第4章 程序的循环控制
第5章 数组
第6章 函数
第7章 基本数据类型
第8章 动手编写各种程序吧
第9章 字符串的基本知识
第10章 指针
第11章 字符串和指针
第12章 结构体
第13章 文件处理
+++++++++++++++++++++++++++++++

第13章 文件处理

13-1 文件与流

代码清单 13-1

//打开与关闭文件

#include <stdio.h>

int main()
{
	FILE *fp;

	fp=fopen("abc","r");

	if(fp == NULL)
	{
		printf("\a无法打开文件\"abc\"。\n");
	}
	else
	{
		printf("\a成功打开了文件\"abc\"。\n");
		fclose(fp);
	}

	return 0;
}

练习 13-1

//修改代码清单13-1,自定义打开的文件名

#include <stdio.h>

int main()
{
	FILE *fp;
	char fn[128];

	printf("请输入文件名:");
	scanf("%s",fn);

	fp=fopen(fn,"r");

	if(fp != NULL)
	{
		printf("该文件存在。\n");
		fclose(fp);
	}
	else
	{
		printf("该文件不存在。\n");
	}

	return 0;
}

练习 13-2

//编写程序,从键盘输入文件名,消去文件内容

#include <stdio.h>

int main()
{
	FILE *fp;
	char fn[128];

	printf("请输入文件名:");
	scanf("%s",fn);

	if(fp=fopen(fn,"r")==NULL)
	{
		printf("该文件不存在,已创建新文件。\n");
	}
	else
	{
		printf("已清空文件内容。\n");
	}

	fp=fopen(fn,"w");

	fclose(fp);

	return 0;
}

代码清单 13-2

//读入身高和体重,计算并显示它们的平均值

#include <stdio.h>

int main()
{
	FILE       *fp;
	int        ninzu=0;
	char       name[100];
	double     height,weight;
	double     hsum=0.0;
	double     wsum=0.0;
	char       fn[128];

	printf("请输入文件名:");
	scanf("%s",fn);
	puts("\n数据如下:");

	if((fp=fopen(fn,"r"))==NULL)
	{
		printf("\a文件打开失败。\n");
	}
	else
	{
		while(fscanf(fp,"%s%lf%lf",name,&height,&weight)==3)
		{
			printf("%-10s %5.1f %5.1f\n",name,height,weight);
			ninzu++;
			hsum+=height;
			wsum+=weight;
		}
		printf("----------------------\n");
		printf("平均       %5.1f %5.1f\n",hsum/ninzu,wsum/ninzu);
		fclose(fp);
	}

	return 0;
}

练习 13-3

//改写代码清单13-2,将从文件读入的个人信息按身高排序后显示

#include <stdio.h>

typedef struct
{
	char name[128];
	double height;
	double weight;
}human;

void swap(human *p1,human *p2);

int main()
{
	FILE       *fp;
	int        ninzu=0;
	human      per[100]={0};
	double     hsum=0.0;
	double     wsum=0.0;
	char       fn[128];
	int        i,j;

	printf("请输入文件名:");
	scanf("%s",fn);
	puts("\n按身高升序排列后:");

	if((fp=fopen(fn,"r"))==NULL)
	{
		printf("\a文件打开失败。\n");
	}
	else
	{
		while(fscanf(fp,"%s%lf%lf",per[ninzu].name,&per[ninzu].height,&per[ninzu].weight)==3)
		{
			hsum+=per[ninzu].height;
			wsum+=per[ninzu].weight;
			ninzu++;
		}
		
		for(i=0;i<ninzu-1;i++)
		{
			for(j=ninzu-1;j>i;j--)
			{
				if(per[j-1].height>per[j].height)
				{
					swap(&per[j-1],&per[j]);
				}
			}
		}

		for(i=0;i<ninzu;i++)
		{
			printf("%-10s %5.1lf %5.1lf\n",per[i].name,per[i].height,per[i].weight);
		}
		printf("----------------------\n");
		printf("平均       %5.1f %5.1f\n",hsum/ninzu,wsum/ninzu);
		fclose(fp);
	}

	return 0;
}

void swap(human *p1,human *p2)
{
	human temp=*p1;
	*p1=*p2;
	*p2=temp;
}

代码清单 13-3

//向文件写入程序运行时的日期和时间

#include <stdio.h>
#include <time.h>

int main()
{
	FILE *fp;
	time_t current=time(NULL);
	struct tm *timer=localtime(&current);

	if((fp=fopen("dt_dat1.txt","w"))==NULL)
	{
		printf("\a文件打开失败。\n");
	}
	else
	{
		printf("写入当前日期和时间。\n");
		fprintf(fp,"%d %d %d %d %d %d\n",
				timer->tm_year + 1900,timer->tm_mon + 1,timer->tm_mday,
				timer->tm_hour,timer->tm_min,timer->tm_sec);
		fclose(fp);
	}

	return 0;
}

练习 13-4

//采用代码清单13-2的文件写入形式,编写从键盘读取姓名、身高和体重,并写入文件的程序

#include <stdio.h>

int main()
{
	FILE *fp;
	char name[128];
	double height;
	double weight;

	if((fp=fopen("hw.dat","a"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		printf("请输入姓名:");	scanf("%s",name);		fprintf(fp,"%-10s",name);
		printf("请输入身高:");	scanf("%lf",&height);	fprintf(fp,"%7.1f",height);
		printf("请输入体重:");	scanf("%lf",&weight);	fprintf(fp,"%7.1f\n",weight);

		fclose(fp);
	}

	return 0;
}

代码清单 13C-1

//显示当前日期和时间

#include <stdio.h>
#include <time.h>

int main()
{
	time_t current=time(NULL);
	struct tm *timer=localtime(&current);

	char *wday_name[]={"日","一","二","三","四","五","六"};

	printf("当前日期和时间为%d年%d月%d日(%s)%d时%d分%d秒。\n",
			timer->tm_year+1900,
			timer->tm_mon+1,
			timer->tm_mday,
			wday_name[timer->tm_wday],
			timer->tm_hour,
			timer->tm_min,
			timer->tm_sec
		  );

	return 0;
}

代码清单 13-4

//显示程序上一次运行时的日期和时间

#include <stdio.h>
#include <time.h>

char data_file[]="datetime.dat";

void get_data();
void put_data();

int main()
{
	get_data();

	put_data();

	return 0;
}

void get_data()
{
	FILE *fp;

	if((fp=fopen(data_file,"r"))==NULL)
	{
		printf("本程序第一次运行。\n");
	}
	else
	{
		int year,month,day,h,m,s;

		fscanf(fp,"%d%d%d%d%d%d",&year,&month,&day,&h,&m,&s);
		printf("上一次运行是在%d年%d月%d日%d时%d分%d秒。\n",year,month,day,h,m,s);

		fclose(fp);
	}
}

void put_data()
{
	FILE *fp;
	time_t current=time(NULL);
	struct tm *timer=localtime(&current);

	if((fp = fopen(data_file,"w")) == NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		fprintf(fp,"%d %d %d %d %d %d\n",
				timer->tm_year+1900,
				timer->tm_mon+1,
				timer->tm_mday,
				timer->tm_hour,
				timer->tm_min,
				timer->tm_sec
			  );
		fclose(fp);
	}
}

练习 13-5

//显示程序上一次运行的时间和当时的心情

#include <stdio.h>
#include <time.h>

char data_file[]="datetime.dat";

void get_data();
void put_data();

int main()
{
	get_data();

	put_data();

	return 0;
}

void get_data()
{
	FILE *fp;

	if((fp=fopen(data_file,"r"))==NULL)
	{
		printf("本程序第一次运行。\n");
	}
	else
	{
		int year,month,day,h,m,s;
		char mood[160];

		fscanf(fp,"%d%d%d%d%d%d%s",&year,&month,&day,&h,&m,&s,&mood);
		printf("上一次运行是在%d年%d月%d日%d时%d分%d秒,%s!\n",year,month,day,h,m,s,mood);

		fclose(fp);
	}
}

void put_data()
{
	FILE *fp;
	time_t current=time(NULL);
	struct tm *timer=localtime(&current);
	char mood[160];

	printf("当前的心情:");
	scanf("%s",&mood);

	if((fp=fopen(data_file,"w"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		fprintf(fp,"%d %d %d %d %d %d\n",
				timer->tm_year+1900,
				timer->tm_mon+1,
				timer->tm_mday,
				timer->tm_hour,
				timer->tm_min,
				timer->tm_sec
			   );
		fprintf(fp,"%s\n",mood);

		fclose(fp);
	}
}

代码清单 13-5

//将标准输入的数据复制到标准输出

#include <stdio.h>

int main()
{
	int ch;

	while((ch=getchar()) != EOF)
	{
		putchar(ch);
	}

	return 0;
}

代码清单 13-6

//显示文件内容

#include <stdio.h>

int main()
{
	int ch;
	FILE *fp;
	char fn[FILENAME_MAX];

	printf("文件名:");
	scanf("%s",fn);

	if((fp=fopen(fn,"r"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		while((ch=fgetc(fp)) != EOF)
		{
			putchar(ch);
		}

		fclose(fp);
	}

	return 0;
}

练习 13-6

//编写编程实现从键盘计入文件名,计算文件行数并显示

#include <stdio.h>

int main()
{
	FILE *fp;
	char fn[FILENAME_MAX];
	int ch;

	printf("文件名:");
	scanf("%s",fn);

	if((fp=fopen(fn,"r"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		int LineNum=0;

		while((ch=fgetc(fp)) != EOF)
		{
			if(ch=='\n')
			{
				LineNum++;
			}
		}
		printf("文件总共有%d行。\n",LineNum);
		
		fclose(fp);
	}
}

练习 13-7

//编写编程实现从键盘计入文件名,计算文件的字符数并显示

#include <stdio.h>

int main()
{
	FILE *fp;
	char fn[FILENAME_MAX];
	int ch;

	printf("文件名:");
	scanf("%s",fn);

	if((fp=fopen(fn,"r"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		long CS=0;

		while((ch=fgetc(fp)) != EOF)
		{
			CS++;
		}
		printf("文件总共有%ld个字符。\n",CS);

		fclose(fp);
	}
}

代码清单 13-7

//复制文件

#include <stdio.h>

int main()
{
	FILE *sfp;
	FILE *dfp;
	char sfn[FILENAME_MAX];
	char dfn[FILENAME_MAX];
	int ch;

	printf("打开原文件:");		scanf("%s",sfn);
	printf("打开目标文件:");	scanf("%s",dfn);

	if((sfp=fopen(sfn,"r"))==NULL)
	{
		printf("原文件打开失败。\n");
	}
	else
	{
		if((dfp=fopen(dfn,"w"))==NULL)
		{
			printf("目标文件打开失败。\n");
		}
		else
		{
			while((ch=fgetc(sfp)) != EOF)
			{
				fputc(ch,dfp);
			}

			printf("文件已复制。\n");

			fclose(dfp);
		}

		fclose(sfp);
	}

	return 0;
}

练习 13-8

//修改代码清单13-7,复制文件同时在屏幕上显示文件内容

#include <stdio.h>

int main()
{
	FILE *sfp;
	FILE *dfp;
	char sfn[FILENAME_MAX];
	char dfn[FILENAME_MAX];
	int ch;

	printf("打开原文件:");		scanf("%s",sfn);
	printf("打开目标文件:");	scanf("%s",dfn);

	if((sfp=fopen(sfn,"r"))==NULL)
	{
		printf("原文件打开失败。\n");
	}
	else
	{
		if((dfp=fopen(dfn,"w"))==NULL)
		{
			printf("目标文件打开失败。\n");
		}
		else
		{
			while((ch=fgetc(sfp)) != EOF)
			{
				putchar(ch);
				fputc(ch,dfp);
			}

			printf("文件已复制。\n");

			fclose(dfp);
		}

		fclose(sfp);
	}

	return 0;
}

练习 13-9

//修改代码清单13-7,将文件内的小写字母转换成大写字母并复制文件

#include <stdio.h>
#include <ctype.h>

int main()
{
	FILE *sfp;
	FILE *dfp;
	char sfn[FILENAME_MAX];
	char dfn[FILENAME_MAX];
	int ch;

	printf("打开原文件:");		scanf("%s",sfn);
	printf("打开目标文件:");	scanf("%s",dfn);

	if((sfp=fopen(sfn,"r"))==NULL)
	{
		printf("原文件打开失败。\n");
	}
	else
	{
		if((dfp=fopen(dfn,"w"))==NULL)
		{
			printf("目标文件打开失败。\n");
		}
		else
		{
			while((ch=fgetc(sfp)) != EOF)
			{
				fputc(toupper(ch),dfp);
			}

			printf("文件已复制。\n");

			fclose(dfp);
		}

		fclose(sfp);
	}

	return 0;
}

练习 13-10

//修改代码清单13-7,将文件内的大写字母转换成小写字母并复制文件

#include <stdio.h>
#include <ctype.h>

int main()
{
	FILE *sfp;
	FILE *dfp;
	char sfn[FILENAME_MAX];
	char dfn[FILENAME_MAX];
	int ch;

	printf("打开原文件:");		scanf("%s",sfn);
	printf("打开目标文件:");	scanf("%s",dfn);

	if((sfp=fopen(sfn,"r"))==NULL)
	{
		printf("原文件打开失败。\n");
	}
	else
	{
		if((dfp=fopen(dfn,"w"))==NULL)
		{
			printf("目标文件打开失败。\n");
		}
		else
		{
			while((ch=fgetc(sfp)) != EOF)
			{
				fputc(tolower(ch),dfp);
			}

			printf("文件已复制。\n");

			fclose(dfp);
		}

		fclose(sfp);
	}

	return 0;
}

13-2 文本和二进制

代码清单 13-8

//将圆周率的值写入文本文件,再进行读取

#include <stdio.h>

int main()
{
	FILE *fp;
	double pi=3.14159265358979323846;

	printf("从变量pi得到的圆周率为%23.21f。\n",pi);

	if((fp=fopen("PI.txt","w"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		fprintf(fp,"%f",pi);

		fclose(fp);
	}

	if((fp=fopen("PI.txt","r"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		fscanf(fp,"%lf",&pi);
		printf("从文件读取的圆周率为%23.21f。\n",pi);

		fclose(fp);
	}

	return 0;
}

代码清单 13-9

//将圆周率的值写入二进制文件再进行读写

#include <stdio.h>

int main()
{
	FILE *fp;
	double pi=3.14159265358979323846;

	printf("从变量pi得到的圆周率为%23.21f。\n",pi);

	if((fp=fopen("PI.bin","wb"))==NULL)
	{
		printf("打开文件失败。\n");
	}
	else
	{
		fwrite(&pi,sizeof(double),1,fp);

		fclose(fp);
	}

	if((fp=fopen("PI.bin","rb"))==NULL)
	{
		printf("打开文件失败。\n");
	}
	else
	{
		fread(&pi,sizeof(double),1,fp);

		printf("从文件读取的圆周率为%23.21f。\n",pi);

		fclose(fp);
	}
 
	return 0;
}

练习 13-11

//编写一个程序,读取含有10个double型元素的数组的所有元素值

#include <stdio.h>

int main()
{
	FILE *fp;
	double d[10];
	int i;

	if((fp=fopen("DoubleArray.bin","wb"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		for(i=0;i<10;i++)
		{
			printf("d[%d]:",i+1);
			scanf("%lf",&d[i]);
		}

		fwrite(d,sizeof(double),10,fp);

		fclose(fp);
	}

	if((fp=fopen("DoubleArray.bin","rb"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		fread(d,sizeof(double),10,fp);

		for(i=0;i<10;i++)
		{
			printf("d[%d]:%23.21f\n",i+1,d[i]);
		}

		fclose(fp);
	}

	return 0;
}

练习 13-12

//改写代码清单13-4,将日期和时间作为struct tm型的值直接向二进制文件进行读写操作

#include <stdio.h>
#include <time.h>

char data_file[]="datetime.bin";

void put_data();
void get_data();

int main()
{
	get_data();

	put_data();

	return 0;
}

void get_data()
{
	FILE *fp;
	struct tm GetTime;

	if((fp=fopen(data_file,"rb"))==NULL)
	{
		printf("本程序第一次运行。\n");
	}
	else
	{
		fread(&GetTime,sizeof(struct tm),1,fp);

		printf("上一次运行是在%d年%d月%d日%d时%d分%d秒。\n",
				GetTime.tm_year+1900,
				GetTime.tm_mon+1,
				GetTime.tm_mday,
				GetTime.tm_hour,
				GetTime.tm_min,
				GetTime.tm_sec
			   );

		fclose(fp);
	}
}

void put_data()
{
	FILE *fp;
	time_t current=time(NULL);
	struct tm *PutTime=localtime(&current);
	
	if((fp=fopen(data_file,"wb"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		fwrite(PutTime,sizeof(struct tm),1,fp);	//因此处PutTime本身为指针变量,所以不用加&

		fclose(fp);
	}
}

代码清单 13-10

//用字符和字符编码显示文件内容

#include <stdio.h>
#include <ctype.h>

int main()
{
	int n;
	unsigned long count=0;
	unsigned char buf[16];
	FILE *fp;
	char fn[FILENAME_MAX];

	printf("文件名:");
	scanf("%s",fn);

	if((fp=fopen(fn,"rb"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		while((n=fread(buf,1,16,fp))>0)
		{
			int i;

			printf("%08lX ",count);
			
			for(i=0;i<n;i++)
			{
				printf("%02X ",(unsigned)buf[i]);
			}
			
			if(n<16)
			{
				for(i=n;i<16;i++)
				{
					printf("   ");
				}
			}

			for(i=0;i<n;i++)
			{
				putchar(isprint(buf[i])?buf[i]:'.');
			}

			putchar('\n');

			count+=16;
		}

		fclose(fp);
	}

	return 0;
}

练习 13-13

//复制文件(二进制方式)

#include <stdio.h>

int main()
{
	FILE *sfp;
	FILE *dfp;
	char sfn[FILENAME_MAX];
	char dfn[FILENAME_MAX];
	int ch;

	printf("打开原文件:");		scanf("%s",sfn);
	printf("打开目标文件:");	scanf("%s",dfn);

	if((sfp=fopen(sfn,"rb"))==NULL)
	{
		printf("原文件打开失败。\n");
	}
	else
	{
		if((dfp=fopen(dfn,"wb"))==NULL)
		{
			printf("目标文件打开失败。\n");
		}
		else
		{
			while((fread(&ch,1,1,sfp)) > 0)
			{
				fwrite(&ch,1,1,dfp);
			}

			printf("文件已复制。\n");

			fclose(dfp);
		}

		fclose(sfp);
	}

	return 0;
}

总结

summary

//将标准输入的数据写入文件

#include <stdio.h>\

int main()
{
	int ch;
	FILE *fp;
	char fn[FILENAME_MAX];

	printf("文件名:");
	scanf("%s",fn);

	if((fp=fopen(fn,"w"))==NULL)
	{
		printf("文件打开失败。\n");
	}
	else
	{
		while((ch=fgetc(stdin)) != EOF)
		{
			fputc(ch,fp);
		}

		fclose(fp);
	}

	return 0;
}
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值