C语言-----文件简述

文件是当今计算机系统不可或缺的一部分.文件用于存储程序、文档、数据、书信、表格、图形、照片、视频、和许多其他种类的信息。作为程序员,必须会编写创建文件和从文件读写数据的程序。接下来将对文件进行简述。

文本文件和二进制文件的区别是什么???

 文本文件和二进制文件就其存放内容而言,均为二进制形式(0或1)存储。但是,对于文本文件而言,其最初使用二进制编码的字符(例如ASCII或Unicode)表示文本,其中包含文本内容;而对于二进制文件而言,其二进制值代码机器语言代码或数值数据或图片或音乐编码,其中包含二进制内容。

文本模式和二进制模式的区别是什么???

关于这个问题,可以参考下面这篇博客的讲解:

https://blog.csdn.net/zrf2112/article/details/51996003

下面我们对一些标准I/O函数进行介绍。

<1>fopen()函数

函数原型:

#include<stdio.h>

FILE *fopen(const char *filename,const char *mode);

参数说明:

filename:表示欲打开的文件路径及文件名;

 mode:一个字符串,指定代打开文件的模式。

详细的模式字符串如下表格所示:

fopen()的模式字符串
模式字符串含义
“r”以只读模式打开文件
“w”以写模式打开文件,把现有文件的长度截为0,如果文件不存在,则创建一个新文件。
“a”以写模式打开文件,在现有的文件末尾添加内容,如果文件不存在,则创建一个新文件。
“r+”以更新模式打开文件(即可以读写文件)。
“w+”以更新模式打开文件(即,读和写),如果文件存在,则将其长度截为0;如果文件不存在,则创建一个新的文件;
“a+”以更新模式打开文件(即,读和写),在现有文件的末尾添加内容;如果文件不存在,则创建一个新的文件;可以读整个文件,但是只能从文件末尾添加内容。
“rb”、“wb”、“ab”、“rb+”、“r+b”、“wb+”与上一个模式对应,但是是以二进制模式而不是以文本模式打开文件

 

返回值:程序调用成功,返回一个非空的文件指针,调用失败,返回NULL。

例子:

#include<stdio.h>
int main()
{
   char *path = "E://a.txt";
   FILE *pf = fopen(path,"r");   //以只读形式打开文件
   if(NULL == pf)
   {
         printf("Don't open the file!\n");
         exit(EXIT_FAILURE);
   }

   fclose(pf);          //关闭文件
   return 0;
}

<2>getc()函数

函数原型:

#include<stdio.h>

int getc(FILE *stream);

功能:用函数getc从文件读取字符。getc()函数与getchar函数类似。所不同的是,要告诉getc函数使用哪一个文件。

例如:从标准输入中获取一个字符”:ch = getchar();

           从fp指定的文件中获取一个字符":ch = getc(fp);

返回值:读取失败或者到了文件结束标志返回EOF。

<3>pusc()函数

函数原型:

#include<stdio.h>

int putc(int c,FILE *stream);

功能:在fp所指向的文件的当前读写位置写入一个字符。putc()函数与putchar()函数类似。所不同的是,putc()函数使用哪一个文件。

例如: 从标准输出中获取一个字符":putchar();

            把字符ch放入FILE指针fp指定的文件中":putc(ch,fp);

返回值:写入字符成功则函数返回值为该字符的ASCII值,写入字符不成功则返回值为EOF。

<4>flcose()函数

函数原型:

#include<stdio.h>

int close(FILE *stream);

 功能:fclose(fp)函数关闭fp指定的文件。

返回值:调用成功返回0,调用失败返回EOF。

<5>fprintf()和fscanf()函数

函数原型:

#include<stdio.h>

int fprintf(FILE *stream,const char *format,...);
int fscanf(FILE *stream,const char *format,...);

参数说明:

stream:文件指针

format:输出格式

功能:fprintf()和fscanf()函数工作方式和printf()和scanf()类似,区别在于前者需要第一个参数指定一个待处理的文件。

<6>sprintf()和sscanf()函数

函数原型:

#include<stdio.h>

int sprintf(char *s,const char *format,...);
int sscanf(const char *s,const char *format,...);

 功能:fprintf()和fscanf()函数工作方式和printf()和scanf()类似,区别在于前者需要第一个参数指定一个待处理的字符串。

<7>fgets()函数

函数原型:

#include<stdio.h>

char *fgets(char *buf, int bufsize, FILE *stream);

参数说明:

buf: 字符型指针,指向用来存储所得数据的地址。

bufsize: 整型数据,指明存储数据的大小。

stream: 文件结构体指针,将要读取的文件流。

功能:从文件结构体指针stream中读取数据,每次读取一行。读取的数据保存在buf指向的字符数组中,每次最多读取bufsize-1个字符(第bufsize个字符赋'\0'),如果文件中的该行,不足bufsize-1个字符,则读完该行就结束。如若该行(包括最后一个换行符)的字符数超过bufsize-1,则fgets只返回一个不完整的行。

返回值:成功,则返回第一个参数buf;如果发生读入错误,error指示器被设置,返回NULL,buf的值可能被改变。

<8>fputs()函数

函数原型:

#include<stdio.h>

int fputs(const char *str, FILE *stream);

功能:把字符串写入到指定的流( stream) 中,但不包括空字符。

参数说明:

str:这是一个数组,包含了要写入的以空字符终止的字符序列。

stream:指向 FILE 对象的指针,该 FILE 对象标识了要被写入字符串的流

返回值:该函数返回一个非负值,如果发生错误则返回 EOF。

<9>fflush()函数

函数原型:

#include<stdio.h>

int fflush(FILE *stream)

功能:清除读写缓冲区,需要立即把输出缓冲区的数据进行物理写入时。如果参数stream 为NULL,fflush()会将所有打开的文件数据更新。

返回值:如果成功刷新,fflush返回0。指定的流没有缓冲区或者只读打开时也返回0值;否则返回EOF。
<10>ungetc()函数

函数原型:

#include<stdio.h>

int ungetc(int c, FILE *stream);

参数说明:

c: 要写入的字符;

stream:文件流指针,必须是输入流不能是输出流

功能:把c指定的字符放回输入流中

返回值:操作成功返回字符c, 操作失败返回EOF。

<11>ftell()函数

函数原型:

#include<stdio.h>

long ftell(FILE *stream);

参数说明:

stream:FILE指针,指向待查找的文件;

offset:偏移量,表示从起始点开始要移动的距离;

fromwhere:起始点模式,该参数确定了起始点;

几种起始点模式如下表格所示:


 

文件的起始点模式
模式偏移量的起始点
SEEK_SET文件开始处

SEEK_CUR

当前位置
SEEK_END文件末尾

功能:用于得到文件位置指针当前位置相对于文件首的偏移字节数。fell()函数一般和fseek()函数一起使用。

说明:由于返回值是long类型,而long类型的取值存在范围,故当文件大小大于2.1G时可能会出现错误。

<12>fseek()函数

函数原型:

#include<stdio.h>

int fseek(FILE *stream, long offset, int fromwhere);

功能:重定位流(数据流/文件)上的文件内部位置指针。


例如:

fseek(fp ,0L , SEEK_SET);          //定位至文件开始处

fseek(fp , 10L, SEEK_SET);        //定位至文件中的第10个字节

fseek(fp , 2L, SEEK_CUR);          //从文件当前位置前移2个字节

fseek(fp , -10L, SEEK_END);      //从文件结尾处回退10个字节 

<13>fgetpos()和fsetpos()函数

函数原型:

#include<stdio.h>

int fgetpos(FILE * restrict stream,fpos_t * restrict pos);
int fsetpos(FILE *stream, const fpos_t *pos);

功能:fseek()和ftell()存在的问题就是,他们都把文件限制在long类型能表示的范围内。这个大小可能不能满足满足人们对于文件操作的需求。所以,产生了两个新的函数:fgetpos()和fsetpos()函数,这两个函数没有使用long,而是使用了fpos_t类型,他不是一个基本类型,而是根据其他类型定义的。

返回值:成功返回0,失败返回非0。

例子:

int main()
{
	FILE* stream;
	char string[]="This is a test";
	fpos_t filepos;
	fpos_t filepos2 = 3;
	stream = fopen("E:\\a.txt","w+");
	fwrite(string,strlen(string),1,stream);
	/*report the file pointer position*/
	fgetpos(stream,&filepos);
	printf("The file pointer is at byte:\%ld\n",filepos);

	fsetpos(stream,&filepos2);
	fgetpos(stream,&filepos);
	printf("The file pointer is at byte:\%ld\n",filepos);
	
	fclose(stream);
	return 0;
}

<14>fread()函数

函数原型:

#include<stdio.h>

size_t fread ( void *buffer, size_t size, size_t count, FILE *stream) ;

参数解释:

buffer:用于接收数据的内存地址;

size:要读的每个数据项的字节数,单位是字节;

count:要读count个数据项,每个数据项size个字节;

stream:输入流

功能:fread是一个函数,它从文件流中读数据,最多读取count个项,每个项size个字节,如果调用成功返回实际读取到的项个数(小于或等于count),如果不成功或读到文件末尾返回 0。

 返回值:返回真实读取的项数,若大于count则意味着产生了错误。

<15>fwrite()函数

函数原型:

#include <stdio.h>

size_t fwrite(const void* buffer, size_t size, size_t count, FILE* stream);

参数解释:

buffer:是一个指针,对fwrite来说,是要获取数据的地址;

size:要写入内容的单字节数;

count:要进行写入size字节的数据项的个数;

stream:目标文件指针;

返回值:返回实际写入的数据项个数count。

<16>setvbuf()函数

函数原型:

#include<stdio.h>

int setvbuf(FILE *stream, char *buf, int type, unsigned size);

参数说明:

type : 期望缓冲区的类型:

  • _IOFBF(满缓冲):当缓冲区为空时,从流读入数据。或者当缓冲区满时,向流写入数 据。
  • _IOLBF(行缓冲):每次从流中读入一行数据或向流中写入一行数据。
  • _IONBF(无缓冲):直接从流中读入数据或直接向流中写入数据,而没有缓冲区。

size : 缓冲区内字节的数量。

功能:用于设定文件流的缓冲区。

<17>feof()和ferror()函数

函数原型:

#include<stdio.h>

int feof(FILE *fp);
int ferror(FILE *fp);

功能:如果标准输入函数返回EOF,则通常表明函数已达到文件末尾。然而,出现读取错误时,函数也会返回EOF。feof()和ferror()函数用于区分两种情况。当上一次输入调用检查到文件末尾时,feof()函数返回一个非零值,否则返回0.当读或者写发生错误,ferror()函数返回一个非零值,否则返回0。

函数应用示例:

1.将桌面上的一个.txt文件拷贝到E:中;

代码实现:

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

int main()
{
	char *path = "E:\\C++.png";
	char *path2 = "C:\\Users\\lenovo\\Desktop\\STL二级空间配置器.png";
	FILE *pr = fopen(path2,"rb");
	FILE *pw = fopen(path,"wb");
	if(NULL == pr)
	{
		printf("1not open the file!\n");
	}
	if(NULL == pw)
	{
		printf("2not open the file!\n");
	}
	char buff[1024] = {0};
	while(fread(buff,1,1024,pr) > 0)
	{
		fwrite(buff,1,1,pw);
	}
	fclose(pr);
	fclose(pw);
	return 0;
}

2.//把一系列文件的内容附加到另外一个文件的末尾;

代码实现:

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#define BUFSIZE 4096
#define SLEN 81


void append(FILE *source,FILE *dest)
{
	size_t bytes;
	static char temp[BUFSIZE];

	while((bytes = fread(temp,sizeof(char),BUFSIZE,source)) > 0)
	{
		fwrite(temp,sizeof(char),bytes,dest);
	}
}

char *s_gets(char *st,int n)
{
	char *ret_val;
	char *find;

	ret_val = fgets(st,n,stdin);
	if(ret_val)
	{
		find = strchr(st,'\n');
		if(find)
		{
			*find = '\0';
		}
		else
		{
			while(getchar() != '\n')
			{
				continue;
			}
		}
		return ret_val;
	}
}

int main()
{
	FILE *fa,*fs;          //fa指向目标文件,fs指向源文件
	int files = 0;         //附加的文件数量
	char file_app[SLEN];   //目标文件名
	char file_src[SLEN];   //源文件名
	int ch;

	puts("Enter name of destination file:");
	s_gets(file_app,SLEN);
	if((fa = fopen(file_app,"a+")) == NULL)     //打开目标文件
	{
		fprintf(stderr,"Can't open %s\n",file_app);
		exit(EXIT_FAILURE);
	}

	if(setvbuf(fa,NULL,_IOFBF,BUFSIZE) != 0)   
	{
		fputs("Can't create output buffer\n",stderr);
		exit(EXIT_FAILURE);
	}

	puts("Enter name of first source file(empty line to quit):");
	while(s_gets(file_src,SLEN) && file_src[0] != '\0')
	{
		if(strcmp(file_src,file_app) == 0)    //防止程序把文件附加在自身末尾
		{
			fputs("Can't append file to itself\n",stderr);
		}
		else if((fs = fopen(file_src,"r")) == NULL)   //以只读形式打开源文件
		{
			fprintf(stderr,"Can't open %s\n",file_src);
		}
		else
		{
			if(setvbuf(fs,NULL,_IOFBF,BUFSIZE) != 0)
			{
				fputs("Can't create output buffer\n",stderr);
				continue;
			}

			append(fs,fa);

			if(ferror(fs) != 0)
			{
				fprintf(stderr,"Error in reading file %s.\n",file_src);
			}

			if(ferror(fa) != 0)
			{
				fprintf(stderr,"Error in writing file %s.\n",file_app);
			}

			fclose(fs);

			files++;
			printf("File %s appended.\n",file_src);
			puts("Next file (empty line to quit):");
		}
	}

	printf("Done appending.%d files appended.\n",files);
	rewind(fa);
	printf("%s contents:\n",file_app);
	while((ch = getc(fa)) != EOF)
	{
		putchar(ch);
	}
	puts("Done displaying");
	fclose(fa);
	return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值