C语言之文件操作

目录

1.文件的概念  

2.使用文件的目的

3.文件的分类:

3.1.按文件存储的外部设备分类

3.2.按系统对文件的处理方法分类

4.文件类型指针

5.文件的操作(文件的打开与关闭)

6.文件内部读写位置指针

7.文件尾检测

            EOF(仅用于文本文件)  

            feof(pf)  

8.文件中单个文件的操作

           字符输入函数fgetc   

           字符输出函数fputc   

9.文件中的字符串读写操作

            字符串输入函数fgets

            字符串输出函数fputs

10.文件中的格式化读写操作

            格式化输入函数fscanf

            格式化输出函数fprintf

11.文件中的数据块读写操作

            数据块输出函数fwrite

            数据块输入函数fread

12.文件的操作位置指针和文件定位

            获取文件内部记录指针当前位置  

            重置文件内部记录指针

            设置文件内部记录指针的位置  


 


1.文件的概念  

文件是程序设计中一种重要的数据类型。所谓“文件”就是一个有名字的、存储在某种介质上的、相关信息的集合。如一批二进制数、一组数据、一个程序,图形、图象、声音、计算机外部设备等。

2.使用文件的目的

将数据永久地保存在计算机外部存储介质上,使之成为可以共享的信息。通过文件还可以与其他信息处理系统联系; 可以进行大量的原始数据的输入和保存,以适应计算机系统在各方面的应用;

3.文件的分类:

按文件的结构形式分类 二进制文件  二进制文件是把内存中的数据按其在内存中的存储形式原样存放到计算机外部存储设备。 文本文件  文本文件是全部由字符组成的具有行列结构的文件,即文件的每个元素都是字符或换行符,文本文件又称为ASCII码文件。 按文件的读写方式分类 顺序文件  C语言中将文件看成是一个字符流,并不考虑其存储时的界限,对文件的读写是以字符或字节为单位程序的控制而不是受回车换行符的控制。这种文件一般称之为“流式文件”。 随机文件  具有随机读写功能的文件称为随机文件。在随机文件中,对文件任一元素的读写不必象顺序文件那样从头开始,而是可以直接对文件的某一元素进行访问。

3.1.按文件存储的外部设备分类

  • 磁盘文件

在程序的运行过程中,通常需要将一些数据信息输出到磁盘上保存起来,需要的时候再从磁盘中将其输入到内存进行处理,这种保存在磁盘上的文件称为磁盘文件。

  • 设备文件

在C程序的设计中,将所有的计算机系统外部设备都作为文件对待,这样的文件称为设备文件。有三个称为标准系统设备的特殊设备文件,它们由系统分配和控制,这三个设备文件是:   

  •  标准输入文件stdin:            由系统指定为键盘     
  •  标准输出文件stdout:          由系统指定为显示器     
  • 标准错误输出文件stderr:    由系统指定为显示器    
  • (三个标准系统设备文件进入系统时自动打开,退出系统时自动关闭 ) 

3.2.按系统对文件的处理方法分类

  •  缓冲文件系统

系统自动在内存中为每个正在使用的文件开辟一个缓冲区。 从内存输出数据到磁盘文件:   内存→系统缓冲区→磁盘 从磁盘文件输入数据到内存:   磁盘→系统缓冲区→内存  

  • 非缓冲文件系统

系统不自动为程序开辟确定大小的文件缓冲区,由程序为每个正在使用的文件设置并管理缓冲区。 

4.文件类型指针

文件类型

文件类型是由系统建立的一个结构体类型,其类型名为FILE,在头文件中已经定义。 使用缓冲文件系统,当要求打开/建立一个文件时系统自动在系统内部定义一个FILE数据类型的结构体变量,将该文件的各种描述信息和控制信息存放在该结构体变量中。如文件名字、文件的状态、文件读写指针的当前位置等。 在C语言中,通过指向这个FILE类型结构体变量的指针来操作文件。

在c语言中以结构体方式定义:

C语言之文件操作_第1张图片

5.文件的操作(文件的打开与关闭)

  • 文件进行操作的一般步骤
  1. 打开/建立要操作的文件;
  2. 对文件进行处理(读写等操作);
  3. 关闭被操作的文件;

文件的打开

用标准函数fopen实现打开/建立文件的操作

  fopen函数的使用形式为:  

FILE *fpt;    /* 指向文件类型的指针变量fpt */     

fpt=fopen(file_name,file_mode);  

file_name  将要访问的文件名字,可以使用值为字符串类型的变量或用双引号括起来的字符串常量;    

file_mode  指定文件模式,即文件操作方式。

文件操作方式:

file_mode

功     能

“r”

只读(read),以只读方式打开一个已有的文本文件,若文件不存在返回空指针NULL

“w”

只写(weite),用于向文件输出数据,若文件已经存在则将文件删除,否则创建新的空文件

“a”

追加(append),用于向以存在的文件追加数据,若文件不存在,提示出错。

“rb”

以只读方式打开一个已有的二进制文件

“wb”

以只写方式建立一个二进制文件

“ab”

以添加方式打开/建立一个二进制文件

注意:如果要打开/建立读写模式的文件,在上述对应模式上添“+”加号表示,例如, “r+”表示打开以读方式为主的读写文本文件。

附详细说明: 

C语言之文件操作_第2张图片

文件的打开  

 fopen函数正常地打开或建立了指定文件时,将返回系统中建立的文件类型结构体变量的地址;若fopen函数没有正常地完成打开或建立文件的任务,则会带回一个出错信息并返回一个空指针值NULL。

例子:

1.以只写的方式打开当前目录的文本文件test.txt.可用下列方法

FILE  *fp;  //定义文件指针变量fp

fp=open("test.txt","w");

 2.以只读的方式打开d盘test目录下的二进制文件test.dat,采用下列方法:

FILE *p;   //定义文件指针变量
fp =open("d:\\test\\test.dat","rb");  //文件路径的分隔符需要用转义字符表示,即两个反斜杠

对fopen的补充说明: 

1.如果文件打开成功,fopen()函数将返回给文件的文件指针,以后就可以通过该文件指针来对文件进行各种操作,而不用再使用文件名。

2.如果文件打开失败,fopen()函数返回空指针NULL.

3.可以通过判断fopen()函数的返回值来确定文件是否正常打开,可以用以下形式:

if(fp=fopen("filename","r")==NULL)
{
    printf("Can not open this file!\n");
    exit(0);
}

文件的关闭  

 使用完文件后应及时地对文件进行关闭,及时关闭文件的理由至少有以下两点: 使用缓冲文件系统时,如果数据缓冲区未满而又不关闭文件就退出程序的运行,则会造成数据缓冲区内的数据丢失。 一个系统内能够同时打开的文件有一定的数量限制。如果不及时地关闭已经不使用的文件,就可能造成打开其他文件时出错。

用标准函数fclose关闭文件  

函数原型:int fclose( FILE *stream );  

调用形式:fclose(文件指针);  

函数功能:将与指定文件指针相关联的文件关闭。   fclose函数正常关闭了文件,返回0,否则返回EOF(-1)。

说明:

1.该函数用于关闭使用fopen()函数打开的文件,一般程序在这之前打开了几个文件,就必须调用fclose()关闭几个文件。

2.标准设备文件stdin、stdout和stderr由系统自动打开,系统会自动关闭。

3.函数正常关闭文件后返回值为0,出错则返回符号常量EOF(值为-1)。

4.若文件关闭后又想再次对这个文件进行操作,需要再一次使用fopen()函数打开文件。

 文件在使用完要执行关闭操作的原因是:

1.在缓冲文件系统中,文件的读写操作是通过缓冲区来实现的,写入数据时,只有当和缓冲区写满后才把整个缓冲区的数据真正写到文件中,如果不关闭文件而直接使程序停止运行,就会造成缓冲区还没有写入文件的数据丢失。

2.每个系统允许打开的文件数量有限,关闭不用的文件可以释放文件指针和读写缓冲区,以便打开其他文件。


6.文件内部读写位置指针

  • 文件指针(程序中必定义)  

文件指针(FILE类型)是用于关联程序中被操作文件,在程序中必须进行定义,当打开一个文件并用文件指针变量关联后,只要不重新赋值文件指针的值是不变的;

  •  文件内部记录指针(程序不必定义)

  打开(或创建)一个文件时,系统自动为打开的文件建立一个文件内部读写位置指针(即文件内部记录指针),该指针在文件读写中,用于指示文件的当前读写位置,每读写一次,文件位置指针自动指向下一个读写位置。


 

7.文件尾检测

文件尾的检测  

程序中需要判断文件是否处理完成,即文件内部记录指针是否已移动到了文件尾标志处。

  • EOF(仅用于文本文件)  

   由于文本文件中任何字符的编码均不是-1,可以用-1表示文本文件的文件尾标志,系统中用符号常量EOF来表示。在输入流中表示为ctrl+z。

  • feof(pf)  

   ANSI C提供了一个测试文件状态的函数feof(pf),当文件未结束时feof函数的值为0,否则为非0值。使用函数feof来判断文件是否结束既可用于文本文件,还可用于二进制文件。


 8.文件中单个文件的操作 

C语言之文件操作_第3张图片

  • 单字符输入函数fgetc   

函数原型:int fgetc(FILE *stream );

函数调用:ch=fgetc(fpt);     //注意,ftp和ch分别为已经定义的文件指针变量和字符变量

函数功能:从指针变量fpt相关联的文件中读取一个字符并将其赋给字符型变量ch;执行函数时遇文件结束符或在执行中出错时返回值为EOF(-1)

 例子:

功能:从键盘输入一个文本文件的名称,并将其内容显示在屏幕上。

解释:

1.文件名一般啊包含为多个字符的字符串,可以定义一个字符数组filename进行存放。

2.要从文件中读取内容,fopen()函数的打开方式可设置为“r".

3.文件打开后可以使用fgetc()函数一个一个的读取字符,然后使用putchar将读到的字符显示到屏幕上,知道文件读完为止。

4.由于fgetc()函数遇到文件尾时返回EOF,因此可构建一个while循环判断文件是否读完。

程序代码如下:

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告
void  main()
{
	FILE *fp;
	char ch, filename[50];
	printf("请输入文件名:");
	gets(filename);
	if ((fp=fopen(filename, "r")) == NULL)  //打开文件
	{	
		printf("打开文件失败!\n");
		exit(0);
	}
	while ((ch = fgetc(fp)) != EOF)  //检测文件读取是否达到尾部
		putchar(ch);   //输出到屏幕上
	fclose(fp);   //关闭文件
	system("pause");

运行程序:

C语言之文件操作_第4张图片

注意事项:

1.有关文件的程序遵循”打开->读写->关闭“的三部曲,运行前需要先新建一个test.tet,文件文件然后写一些字符串进去,把它放置于工程的同一级目录下,通过据对路径就可以找到test.txt文件,这样才能打开成功!

2.在文件内部有一个位置指针,用来指向当前读写字节,使用fgetc()函数后,该位置指针一次向后移动,位置指针和文件指针具有不同含义


  • 单字符输出函数fputc   

函数原型:int fputc(int c, FILE *stream );

函数调用:fputc(ch,fpt);

函数功能:将字符变量ch的值输出到文件指针fpt相关联的文件中。fputc函数执行成功时,返回输出的字符值,当函数执行发生错误则返回EOF(-1)。

注意事项:

使用字符读写函数的几点说明:

  1. fgetc函数所读文件以读或读写方式打开,fputc函数写入文件用写、读写、追加(写入文件尾)方式打开。
  2. 每读写一个字符,文件内部记录指针自动向后移动一个字节。
  3. 字符输入输出函数均有一个返回值。如果读、写成功,返回读取或写入的字符,否则返回文件结束符EOF,以此判断文件是否结束或读写操作是否成功。
  4. putchar()函数向屏幕输出一个字符。可以发现,fputc(c,stdout)可以实现相同的功能,实际上,putchar是通过如下的宏定义由fputc函数派生的:#define putchar(c)  fputc(c,stdout)

例子:

从键盘输入多个字符(以”#“结束),存入到指定文件中。

代码如下:

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告
void  main()
{
	FILE *fp;   //定义一个文件指针变量
	char ch, filename[50];  
	printf("请输入文件名:");
	scanf("%s",filename);
	if ((fp=fopen(filename, "w")) == NULL)  //以w方式打开文件
	{	
		printf("打开文件失败!\n");
		exit(0);
	}
	while ((ch = getchar()) != '#')  //getchar从键盘读取一个字符,判断是否为#字符 
		fputc(ch,fp);   //若不为“#”字符,使用fputc函数将字符写入指定文件中
	fclose(fp);  //关闭文件
	system("pause");
}

运行程序,输入test01.txt,因为是w的方式打开文件,当这个文件不存在时自动创建 

C语言之文件操作_第5张图片

看一看电脑本地test01.txt文件的内容:

C语言之文件操作_第6张图片


9.文件中的字符串读写操作

  • 字符串输入函数fgets

原型:char *fgets( char *string, int n, FILE *stream );

调用:fgets(str,n,fp);

说明:str为保存字符串的内存空间地址,一般为字符串数组名。fp为要读取的文件指针。n为正整数,用于指定读取字符的个数。

功能:从文件指针fpt关联的文件中读取n-1个字符,然后在字符串末尾自动加上’\0’并将它们存放到string所代表的字符串对象中。

函数执行的结束:读入n-1个字符;读入n-1个字符前遇到换行符’\n’;读入n-1个字符前遇到文件结束符EOF;  

函数的返回值:正常结束时返回string对象的首地址,若读到文件尾或出错则返回NULL。

  • 字符串输出函数fputs

原型:int fputs( const char *string, FILE *stream );

调用:fputs(string,fpt);

功能:将string所代表的字符串写入文件指针fpt相关联的文件。函数fputs正常执行时返回写入文件中的字符个数,函数执行出错时返回值为EOF(-1)。

特别提示:使用fputs标准函数向文件中写入字符串时,每写入一个字串后要自行在其后添加一个分隔字符(‘\n’)。

例子:

按行读出文件a.txt中的内容,将其显示在屏幕上,然后将该文件中的内容复制到文件b.txt中

问题分析:

1.本例程涉及两个文件,因此需要定义两个文件指针跟别指向这个两个文件,同时,这两个文件均需要单独打开和关闭。

2.可以使用fgets()和fputs()函数实现文件的按行读/写,使用puts( )在屏幕上显示字符串。

a.txt的内容如下:

C语言之文件操作_第7张图片

代码如下:

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告
void  main()
{
	FILE *in,*out;   //定义两个文件指针变量
	char str[50];  
	if ((in=fopen("a.txt", "r")) == NULL)  //以r方式打开文件a.txt
	{	
		printf("打开文件失败!\n");
		exit(0);
	}
	if ((out = fopen("b.txt", "w")) == NULL)  //以r方式打开文件b.txt
	{
		printf("打开文件失败!\n");
		exit(0);
	}
	//从in指向的文件读取sizeof(str)个字符到str数组当中
	fgets(str,sizeof(str),in);//str为保存字符串的空间地址,第二个参数为指定字符串的读取个数
	                          //第三个参数为读取的文件指针
	while (!feof(in) && str != "")  //getchar从键盘读取一个字符,判断是否为#字符 
	{
		puts(str);        //把字符显示到屏幕上
		fputs(str, out);  //把str字符串写入到out指定的文件中
		fgets(str, sizeof(str), in); //循环把in指向的文件读取到str中,直至结束
	}
	fclose(in);
	fclose(out);
	system("pause");
}

程序说明:

1.while循环中使用feof()函数而没有是有EOF标志检测文件是否结束,可使程序不仅适用于文本文件,还可以用于为二进制文件(rb或wb的打开方式)。同时,另一个检测条件是str!=" ",用于判断文件最后是否为空行。 

2.while循环体中的三条语句分别实现:将读取的字符串输出到屏幕上,将读取的字符串输出到out指向的文件中,读取下一行

运行程序:

C语言之文件操作_第8张图片

看一下b.txt的内容:

C语言之文件操作_第9张图片


 

10.文件中的格式化读写操作

  • fscanf和fprintf()

这两个函数的功能是按照给定的格式输入/输出数据,具体使用方法和scanf和printf基本相同,只不过他们读写的对象不是键盘和屏幕,而是磁盘文件。

  • 格式化输入函数fscanf

 调用:fscanf(fpt,格式控制,地址列表);

 功能:以ASCII码值的方式从fpt关联的文件中读取数据,按格式控制字符串中指定的数据格式转换后送到由输入地址列表中相应项指定的内存单元。函数返回值为正确处理的数据项个数

例子:

如果文件的内容为 ”6,6.6“,则可以使用如下语句读取:

//m和a是已经定义的int类型和double类型的变量

fcanf(fp,"%d,%lf",&m,&a);   //注意此处是地址列表

  • 格式化输出函数fprintf

调用:fprintf(fpt,格式控制,输出表列);

功能:将输出表达式列表的各项由对应格式说明符的格式转换为相应的ASCII码输出到fpt指定的文件中。函数返回值为正确写入文件中字节数。

例子:

如果文件的内容为 ”6,6.6“,则可以使用如下语句读取:

//m和a是已经定义的int类型和double类型的变量

fprintf(fp,"%d,%lf",m,a);    //注意此处不需要地址

 例子:

从键盘当中输入多个小写字符串并写入文件中,再从刚写入的文件中读取并将小写字符改成大写字符显示在屏幕上。

问题分析:

1.可使用fprintf( )向文件中写入字符串,然后通过fscanf()读出字符串。

2.为能够实现多次写入字符串,可使用while循环控制字符串的键盘输入和写入文件,此时需要定义一个变量flag控制循环的进行,(flag=1,继续输入,flag=0,结束循环)。

3.要对文件先写后读,文件的打开方式可选择为w+;

代码如下:

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告
void  main()
{
	FILE *fp;   //定义一个文件指针变量
	int flag=1,i; //定义标志变量
	char str[80],filename[50],ch; 
	printf("请输入文件名:");
	scanf("%s",filename);
	if ((fp=fopen(filename, "w+")) == NULL)  //以r方式打开文件a.txt
	{	
		printf("打开文件失败!\n");
		exit(0);
	}
	while(flag==1)
	{
		printf("请输入小写字母:");
		scanf("%s",str);   //键盘输入保存到str数组中
		fprintf(fp,"%s\n",str);  //格式化输入str到fp指向的文件中
		getchar();   //获取键盘的值,询问是否继续输入
		printf("是否继续(Y/N)?:");
		ch = getchar();
		if (ch == 'N' || ch == 'n')  flag = 0;  //输入n/N把标志位设为0,,退出当前循环	
	}
	rewind(fp); //复位当前文件指针位置
	while (fscanf(fp, "%s", str) != EOF)  //此循环把小写字母换换成大写字母
	{
		for (i = 0; str[i] != '\0'; i++)  //循环直到文件结束为止
		{
			if (str[i] >= 'a'&& str[i] <= 'z')
				str[i] -= 32;  //小写转换成大写	
		}
		printf("%s\n", str);
	}
	
	fclose(fp);
	system("pause");
}

运行程序:

C语言之文件操作_第10张图片

查看b.txt的内容

C语言之文件操作_第11张图片


综合应用例子

要求:编程实现对文件制定文件的内容进行统计,统计处文件中字符、空格、数字及其其他字符的个数,并将统计结果存储到指定文件中。

问题分析:

1.对文件的内容进行统计,只需打开文件后逐个读取字符,然后进行统计

2.要将统计结果输出到指定文件,可以使用fprintf()函数。

in.txt的内容如下:

C语言之文件操作_第12张图片

代码如下:

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告
void  main()
{
	FILE *in,*out;   //定义两个文件指针变量
	char filename1[50],filename2[50],ch; 
	long letter=0, space=0, digit=0, other=0;
	printf("请输入统计的文件名:");
	scanf("%s", filename1);
	if ((in = fopen(filename1, "r")) == NULL) {
		printf("文件打开失败!\n");
		exit(0);
	}
	printf("请输入要写的文件名:");
	scanf("%s", filename2);
	if ((out = fopen(filename2, "w")) == NULL) {
		printf("文件打开失败!\n");
		exit(0);
	}
	while ((ch = fgetc(in)) != EOF) { // 逐个字符读取
		if (ch >= 'A' && ch <= 'Z' || ch >= 'a'&&ch <= 'z')
			letter++;
		else if (ch == ' ')  //空格
			space++;
		else if (ch >= '0'&&ch <= '9')
			digit++;
		else other++;
	}
	fprintf(out,"letter:%1d,space:%1d,digit:%1d,other:%1d\n",letter,space,digit,other);
	fclose(in);
	fclose(out);
	system("pause");
}

运行程序:

C语言之文件操作_第13张图片

查看out.txt的内容:

C语言之文件操作_第14张图片


 

11.文件中的数据块读写操作

数据块读/写函数:fread( )和fwrite( )

fgetc,fputc,fgets和fputs主要用于读/写单个字符和字符串,当要读写实属或者结构体变量等“数据块”形式存储数据时,就要使用fread和fwrite函数。

  • 数据块输出函数fwrite

函数调用:fwrite(buffer,size,count,fp);

burrer 输出数据在内存中的首地址;

Size   要输出的一个数据项的字节数;

count  一次操作输出长度size字节的数据项个数

fp    指向被操作的文件指针。

 功能:将buffer为首地址的连续count个size大小的数据块一次性写入fp指向的文件中。 

 

  • 数据块输入函数fread

 函数调用:fread(buffer,size,count,fp);

burrer 读入数据在内存中的首地址;

size   要读取的一个数据项的字节数; 

count  一次操作读取长度size字节的数据项个数;

fp    指向被操作的文件指针。

功能:从fp 指向的文件中读取count个size大小的数据块,将读出的数据依次存放在buffer为首地址的内存单元中 

  参数说明:

buffer:对于fread来说,是存放读入数据的内存起始地址,对于fwrite来说,是要输入数据内存中的起始地址。

size:要读/写的每个数据项字节数,一般由sizeof运算符计算出。

count:要读/写多少字节的数据项,即读/写的次数。

fp:文件;类型指针,指向要读/写的文件。

例如:

  • 从文件中读入一个整数到变量a当中
fread(&a,sizeof(int),1,fp)  //a为int类型变量
  • 读入5个实数到实型数组b中:
fread(b,sizeof(float),5,fp);  //b为实型数组
  • 有如下的结构体变量
struct tech{
    char name[20];
    char sex;
    int age;
    float salary;   
}techer={"zhangsan","man",30,5000};

要将teacher的值写入fp指向的二进制文件中(以wb的方式打开),可以使用一下语句:

fwrite(&teacher,sizeof(struct tech),1,fp);

例子:

编程实现职工信息(姓名,年龄,工资)录入,要求:从键盘输入职工信息后,保存到指定的文件,输出完毕后将文件中的内容显示在屏幕上。

问题分析:

职工信息可以使用结构体数组进行存储,同时,可定义两个函数用于存入数据和显示数据,并通过main函数进行调用,其中,函数save用于将输入的数据存入文件,show函数用于从文件中读出数据。

代码如下:

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告

//定义结构体
struct employee {
	char name[20];
	int age;
	float salary;
}emp[20]; //定义结构体数据,数量为20个

/*定义save函数,该函数有两个参数:
1.要存入文件名filename 2.职工人数函数无返回值
3.函数体中用wb方式打开文件
4.通过for循环每次写入一个职工的信息,每个职工的信息
占字节数由sizeof(struct employee)给出*/
void save(char filename[], int n)
{
	FILE *fp;
	if ((fp = fopen(filename, "wb")) == NULL) {
		printf("文件打开失败\n");
		exit(0);
	}
	for (int i = 0; i < n; i++)
		if (fwrite(&emp[i], sizeof(struct employee), 1, fp)!=1)
			printf("职工信息写入出错!\n");
	fclose(fp);
}
/*定义show函数,该函数从文件读取职工信息,然后显示到屏幕上
1.以rb方式打开文件
2.使用fread函数从文件中读取数据
3.通过for循环显示职工信息,注:name左对齐,age占4位宽,salary保留一位小数点*/
void show(char filename[],int  n)
{
	FILE *fp;
	if ((fp = fopen(filename, "rb")) == NULL) {
		printf("文件打开失败\n");
		exit(0);
	}
	fread(emp, sizeof(struct employee), n, fp);
	for (int i = 0; i < n; i++)
		printf("\n%-20s%4d%8.1f\n", emp[i].name, emp[i].age, emp[i].salary);
	fclose(fp);
}

/*主函数实现职工信息输入,并保存在文件中,再显示文件中的信息*/

void  main()
{
	int i, n;
	char filename[50];
	printf("请输入总人数:"); scanf("%d", &n);
	printf("请输入文件名:"); scanf("%s",filename);
	printf("请输入姓名 年龄 工资:\n");
	for (i = 0; i < n; i++)
	{
		printf("%-4d:",i + 1);
		scanf("%s,%d,%f", emp[i].name, emp[i].age, emp[i].salary);
	}
	save(filename,n);
	show(filename,n);
	system("pause");
}

运行程序:

C语言之文件操作_第15张图片

查看emp.dat文件的内容:

C语言之文件操作_第16张图片


12.文件的操作位置指针和文件定位

文件内有一个“位置指针”,当打开文件时,该位置指针指向文件首部。当采用文件读/写函数对其进行一次读/写操作后,该位置指针顺序后移到下一个读/写位置,,也就是说,前面介绍的只能对文件进行按顺序读/写。

若希望能实现对文件的堆积读/写,就需要介绍文件定位函数强制改变,包含以下三个函数:

  • 获取文件内部记录指针当前位置  

函数原型:long ftell( FILE *stream );  

函数调用:ftell(fpt);  

函数功能:检测位置指针,ftell函数正常执行时,函数的返回值为相对于文件首部的位移量(长整型),如果出错,则返回值为-1L。

例子:

n=ftell(fp);  //n已定义为long int 类型

 


  • 重置文件内部记录指针

函数原型:void rewind( FILE *stream );

函数调用:rewind(fpt);

函数功能:重置位置指针,将fpt关联文件的文件内部记录指针从任何位置重新拨回文件开头。 

例如:

rewind(fp);  //执行完该函数,之后所有的读写操作权限又从文件首部开始

 


 

  • 设置文件内部记录指针的位置  

 函数原型: int fseek( FILE *stream, long offset, int origin );

 函数调用:fseek(fpt,offset,from);    == fseek(文件指针,位移量,起始点); 

  • fpt 指向关联文件的指针;
  • offset 长整型量表示的文件指针的位移量,指文件指针移动的字节数。正数向后移动,负数向前移动。
  • from  文件内部记录指针的起始位置

文件起始位置的说明:

C语言之文件操作_第17张图片

功能:移动位置指针。

示例:

1.将位置指针移动到离文件首部100字节处

fseek(fp,100L,0);  //fp代表文件指针,100代表偏移量,0代表从首部开始

 2.将位置指针移动到离文件尾部5个字节处

fseek(fp,-5L,SEEK_END);

 3.从当前位置向后移到下一个结构体数据处

fseek(fp,sizeof(struct student),1); //struct student是一个结构体

例子:

从键盘上输入一个文件的名字,求出这个文件的长度,然后显示文本的内容

问题分析:

1.文件打开时,内部位置指针在文件首部,因此,要计算文件的长度,可以使用fseek()函数将位置指针先移动到文件 尾部,再用ftell()求出当前位置,这个结果就是文件长度。

2.求出文件长度后,可使用rewind()函数复位位置指针,再使用fgetc()一次读出文件内容。

新建一个test.dat文件如下:

C语言之文件操作_第18张图片

代码如下:

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告



void  main()
{
	FILE *fp;  //定义一个指针变量fp
	char filename[50], ch;
	long length;
	printf("请输入文件名:");
	scanf("%s",filename);
	if ((fp = fopen(filename, "rb")) == NULL) {
		printf("无法打开文件\n");
		exit(0);
	}
	fseek(fp,0L,2);
	length = ftell(fp);
	printf("文件的长度为:%ld\n",length);
	rewind(fp);
	while (!feof(fp))
	{
		ch = fgetc(fp);
		putchar(ch);
	}
	fclose(fp);
	system("pause");
}

运行程序:

C语言之文件操作_第19张图片

例子2:

在磁盘文件stud.dat上存有10个学生的数据,将1,3,5,7,9个学生的数据读取出来显示在计算机屏幕上。

问题分析:

首先,以rb方式打开文件,然后,在for循环中,利用fseek()将位置指针定位到哟啊显示的数据,利用fread读取数据,利用printf()在屏幕上显示数据。

#include "stdio.h"
#include "stdlib.h"
#pragma warning(disable:4996)  //忽略警告


struct student {
	char name[20];
	int num;
	int age;
	char sex;

}stud[10];

void  main()
{
	FILE *fp;  //定义一个指针变量fp
	char filename[50], ch;
	long length;
	if ((fp = fopen("stud.dat", "rb")) == NULL) {
		printf("无法打开文件\n");
		exit(0);
	}
	for (int i = 0; i < 10; i += 2) {
		fseek(fp, i * sizeof(struct student), 0);   //定位
		fread(&stud[i],sizeof(struct student),1,fp);  //读取文本内容到结构体上
		printf("%s%d",stud[i].name,stud[i].num);
		printf("%d%c", stud[i].age,stud[i].sex);

	}
	fclose(fp);
	system("pause");
}

运行程序:

C语言之文件操作_第20张图片

 

 

 

 

 

 


 

 

 

 

你可能感兴趣的:(网络语言学习)