重新学习C语言的第十三天

本文介绍了C语言中文件的分类,包括特殊文件和普通文件,以及ASCII文件和二进制文件的区别。接着讲解了C语言如何处理文件,包括缓冲文件系统和非缓冲文件系统,并详细阐述了文件的打开与关闭、读写操作,如fopen、fclose、fgetc、fputc等函数的使用。文章还提到了文件结束判断和随机读写操作。

①文件的分类
操作系统是以文件为单位对数据进行管理的。

从用户观点:
1.特殊文件(标准输入输出文件或标准设备文件)
2.普通文件(磁盘文件)
从操作系统的角度看,每一个与主机相连的输入、输出设备看作是一个文件

按数据的组织形式:

ASCII文件(文本文件):每一个字节放一个ASCII代码
二进制文件:把内存中的数据按其在内存中的存储形式原样输出到磁盘上存放。

ASCII文件和二进制文件的比较:

ASCII文件便于对字符进行逐个处理,也便于输出字符。但一般占存储空间较多,而且要花费转换时间。
二进制文件可以节省外存空间和转换时间,但一个字节并不对应一个字符,不能直接输出字符形式。
一般中间结果数据需要暂时保存在外存上,以后又需要输入内存的,常用二进制文件保存。

C语言对文件的处理方法

1.缓冲文件系统:系统自动地在内存区为每一个正在使用的文件开辟一个缓冲区。用缓冲文件系统进行的输入输出又称为高级磁盘输入输出。
2.非缓冲文件系统:系统不自动开辟确定大小的缓冲区,而由程序为每个文件设定缓冲区。用非缓冲文件系统进行的输入输出又称为低级输入输出系统。

C语言对文件的读写都是用库函数来实现的。

②文件的打开与关闭

文件型指针变量:FILE *fp;
fp是一个指向FILE类型结构体的指针变量。
我们使fp指向某一个文件的结构体变量,从而通过该结构体变量中的文件信息能够访问该文件。

1.文件的打开(fopen函数)
函数调用:FILE *fp;
fp=fopen(文件名,使用文件方式);
注意:
需要打开的文件名,也就是准备访问的文件的名字
使用文件的方式(“读”还是“写”等);
让哪一个指针变量指向被打开的文件。

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

int main()
{
	FILE *fp;
	if(!(fp=fopen("E:\\fishc.txt","rb")))  
	{
		printf("Can not open E:\\fishc file!\n");
		system("pause");
	}
	else
	{
		printf("Open success!\n");	
	}
}

2.文件的关闭(fclose函数)
函数调用:
fclose(文件指针);
函数功能:使文件指针变量不指向该文件,也就是文件指针变量与文件“脱钩”,此后不能再通过该指针对原来与其相联系的文件进行读写操作。
返回值:
关闭成功返回值为0;否则返回EOF(-1)

文件的读写
对文件的读和写是最常用的文件操作。在C语言中提供了多种文件读写的函数:
字符读写函数:fgetc和fputc
字符串读写函数:fgets和fputs
数据块读写函数:freed和fwrite
格式化读写函数:fscanf和fprinf

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

int main()
{
	FILE *fp;
	char ch,filename[20];
	
	printf("please input the filename you want to write:");
	scanf("%s",&filename);
	
	if(!(fp=fopen(filename,"wt+")))
	{
		printf("Cannot open the file!\n");
		exit(0);
	}
	printf("please input sentences you want to write:");
	ch=getchar();
	ch=getchar();
	while(ch!=EOF)
	{
		fputc(ch,fp);
		ch=getchar();
	}
	fclose(fp);
	
}

在fgetc()函数调用: ch=fgetc(fp);
其意义是从打开的文件fp中读取一个字符并送入ch中。
在文件内部有一个位置指针。用来指向文件的当前读写字节。在文件打开时,该指针总是指向文件的第一个字节。使用fgetc函数后,该位置指针将向后移动一个字节。因此可连续多次使用fgetc函数,读取多个字符。

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

int main()
{
	FILE *fp;
	char ch,filename[20];
	
	printf("please input the filename you want to write:");
	scanf("%s",&filename);
	
	if(!(fp=fopen(filename,"r")))
	{
		printf("Cannot open the file!\n");
		exit(0);
	}
	while(ch!=EOF)
	{
		ch=fgetc(fp);
		putchar(ch);
	}
	fclose(fp);
	
}

注意:
从一个文本文件顺序读入字符并在屏幕上显示出来:

ch=fgetc(fp);
while(ch!=EOF)
	{
		ch=fgetc(fp);
		putchar(ch);
	}

EOF不是可输出字符,不能在屏幕上显示。由于字符的ASCII码不可能出现-1,因此EOF定义为-1是合适的。当读入的字符值等于-1时,表示读入的已不是正常的字符而是文件结束符。

从一个二进制文件顺序读入字符:
while(!feof(fp)) { ch=fgerc(fp); }
ANSI C提供一个feof()函数来判断文件是否真的结束。如果是文件结束,函数feof(fp)的值为1(真);否则为0(假),以上也使用于文本文件的读取。

大家一起来写文件图片合成器吧~

#include<stdio.h>
#include<stdlib.h>
int main()
{	
	FILE *f_pic,*f_file,*f_finish;
	char pic_name[20],file_name[20],finish_name[20];
	char ch;
	
	printf("请输入需要合成的图片和文件的名称:\n");
	printf("图片:");
	scanf("%s",&pic_name);
	printf("文件:");
	scanf("%s",&file_name);
	printf("生产为:");
	scanf("%s",&finish_name);
	
	if(!(f_pic=fopen(pic_name,"rb")))
	{
		printf("Cannot open the picture %s !",pic_name);
		exit(0);
	}
	if(!(f_file=fopen(file_name,"rb")))
	{
		printf("Cannot open the file %s!",file_name);
		return 0;//exit(0);		
	} 
 	if(!(f_finish=fopen(finish_name,"wb")))
 	{
	 	printf("Cannot open the finishi %s!",finish_name);
		exit(0);	
	 }
	 
	 while(!(feof(f_pic)))
	 {
 		ch=fgetc(f_pic);
		fputc(ch,f_finish);	
 	}
 	fclose(f_pic);
 	while(!(feof(f_file)))
	 {
 		ch=fgetc(f_file);
		fputc(ch,f_finish);	
 	}
 	fclose(f_file);
 	fclose(f_finish); 
	system("pause");
}

字符串输入输出函数(fputs()和fgets())
函数作用:从fp所指的文件中读出n-1个字符送入字符数组str中,因为在最后加一个‘\0’.

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

#define LEN 11
int main()
{
	FILE *fp;
	char butter[LEN];
	if(!(fp=fopen("yangshuai.txt","rt")))
	{
		printf("Cannot open file ");
		exit(1);
	}
	fgets(butter,LEN,fp);
	printf("%s",butter);
	fclose(fp); 
} 

注意,下面这个文本写入

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

#define LEN 100 
int main()
{
	FILE *fp;
	char ch,buffer[LEN];
	if(!(fp=fopen("ys.txt","at+")))
	{
		printf("\nCannot open file strike any key exit!");
		exit(1);
	}
	
	printf("please you want write:\n");
	fgets(buffer,LEN,stdin);//stdin 是从键盘获取的文本信息
	//为什么不用scanf(),因为scanf()函数面对空格就输入完成了 
	fputs(buffer,fp);
	
	 	 
	rewind(fp);//重新定义文件内部指针去到开头处
	ch=fgetc(fp);
	while(ch!=EOF)
	{
		putchar(ch);
		ch=fgetc(fp);	
	}
	printf("\n");
	 
	fclose(fp);
	return 0; 
	
} 

数据块读写函数(fread()和fwrite())
函数调用:fread(buffer,size,count,fp);
fwrite(buffer,size,count,fp);

buffer:是一个指针;
对fread来说,它是读入数据的存放地址。
对fwrite来说,是要输出数据的地址(均指起始地址)。
size:要读写的字节数。
count:要进行读写多少个size字节的数据项。
fp:文件型指针。

从键盘输入4个学生的有关数据,然后把它们以二进制的格式存储到磁盘文件中。

#include<stdio.h>
#include<stdlib.h>
#define SIZE 4

struct student
{
	char name[10];
	int num ;
	int age;
	char addr[15];
} stu[SIZE];
void save()
{
	FILE *fp;
	int i;
	if(!(fp=fopen("student-list","wb")))
	{
		printf("Cannot open the file!\n");
		return ;
	}
	for (i=0;i<SIZE;i++)
	{
		if(fwrite(&stu[i],sizeof(struct student),1,fp)!=1)
		{
			printf("File write error!\n");
			fclose(fp);
		}
	}
}
void load();
int main()
{
	int i;
	printf("Please input the student's name,num,age and address:\n");
	for(i=0;i<SIZE ;i++)
	{
		scanf("%s %d %d %s",&stu[i].name,&stu[i].num,&stu[i].age,&stu[i].addr);
	}
	save();
	load();
	printf(" name num age address\n\n");
	for(i=0;i<SIZE;i++)
	{
		printf("%10s %5d %5d %10s\n",stu[i].name,stu[i].num,stu[i].age,stu[i].addr);
	}
}
void load()
{
	FILE *fp;
	int i;
	if(!(fp= fopen("student-list","r")))
	{
		printf("Cannot open the file!\n");
		return ;
	}
	for(i=0;i<SIZE;i++)
	{
		fread(&stu[i],sizeof(struct student),1,fp);
	}
	fclose(fp);
} 

随机读写

fseek函数(一般用于二进制文件)
函数功能:改变文件的位置指针
函数调用形式:fseek(文件类型指针,位移量,起始点)
起始点:
文件开头 SEEK_SET 0
文件当前位置 SEEK_CUR 1
文件末尾 SEEK_END 2

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

struct student
{
	char name[10];
	int num ;
	int age;
	char addr[15];
} boy;

int main()
{
	FILE *fp;
	int i;//    用于定位第i 个结构
	if(!(fp=fopen("student_list","r")))
	{
		printf("Cannot open the file!\n");
		exit(0);
	} 
	rewind(fp);
	fseek(fp,i*sizeof(struct student),0);
	fread(&boy,sizeof(struct student),1,fp);
	
	printf("name\tnumber\t\tage\t\taddr\n");
	printf("%s\t%5d %7d\t%s\n",boy.name,boy.num,boy.age,boy.addr);
	system("pause");
} 

在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值