C语言学习之文件

  文件是指存储在计算机外部介质上的一组数据的集合。所谓外部存储介质,例如移动硬盘、计算机硬盘、光盘等等。计算机操作系统也是以文件作为基本的操作单位。我们前面编写的程序在运行时,程序中定义的变量或程序的运行结果都是暂时保存在计算机内存空间的,一旦程序运行结束,这些数据所用的空间就会被释放,换句话说这些数据也就消失了。对于需要长期保存的数据,必须以文件的形式存储在外部存储介质上。

    每种高级语言都有其自身的文件处理系统,主要讲述C语言中文件的概念以及如何处理文件的。

 文件概述

      虽然每种语言有其自身的文件处理系统,但有一点是相同的,为区分不同的文件,必须给每个文件取一一个名字,即“文件名”,它的格式为:

      文件名.[扩展名]

      其中的扩展名是按类别命名。在处理文件时是通过“文件名”来找寻文件的。

C语言把文件分为以下两种类型:

      (1)文本文件。又称为ASCII文件,该类文件存放数据时以字节为单位,一个字节存放一个ASCII码:一个ASCII 码就代表一个字符。 可见文本文件就是一组有序的字符, 其文件扩展名为'txt'

      (2)二进制文件。该类文件存放数据是以原始的二进制形式直接存放,不进行任何转换。其文件扩展名为“bin”

文件的基本操作

      无论何种文件系统,对文件进行操作时,都是按照以下步骤进行的:

第一步:打开文件:第二步:处理文件:第三步:关闭文件。

      C语言是利用系统提供的库函数来实现对文件的操作,程序中只需要包含头文件stdio.h就可直接使用这些库函数了。在处理文件之前需要定义文件指针,其定义格式为:

FILE *指针变量名;

例如 FILE *fp;   其中FILE是系统定义的结构体类型,要求大写。”
文件的打开
处理文件必须先打开文件,c语言通过调用fopen函数完成对文件的打开操作, 其通数原型是:
FILE  *fopen(“文件名”,”操作方式”):

若打开文件成功,函数返回一个文件指针;若打开失败,返回NULL;

在编程时,常采用以下方式来判断是否成功打开文件文件,如果“打开成功”,指针fp指向文件开头;如果“打开失败”,即fopen函数返回的是NULL,则利用语句“exit(0);结束程序
FILE *fp:   //定义一个文件指针印P
if((fp=fopen("文件名”,"  操作方式"))==NULL)

{     printf("cannot open flle!");
         exit(0);

}

其中,文件名是要打开的文件名字,它是一个字符串,应该包含”机内存储路径说明”’操作方式是指对打开文件的访问方式.

例9.1、编写程序实现只读方式打开计算机 D盘内的文件file.txt. 

#include <stdio.h>
void main()
{
	FILE *fp;
	if((fp=fopen("D:\\file.txt","r"))==Null)
	{
		printf("cannot open the file\n");
		exit(0);
	}
}

文件的关闭

文件处理结束必须关闭文件,C语言通过调用fclose函数完成关闭文件的操作,其函数原型为:

   int fclose(fp);

其中fp为文件指针类型,它是在打开文件时获得的。如文件关闭成功,返回0;否则返回-1.

#include <stdio.h>
void main()
{
	FILE *fp;
	int i;
	if((fp=fopen("D:\\file.txt","r"))==Null)
	{
		printf("cannot open the file\n");
		exit(0);
	}
	fclose(fp);  //关闭打开的文件‘
	if(i==0)
		printf("OK");
	else
		printf("file close error");
}

其实无需像上面那样判断函数的返回值,直接使用语句fclose(fp);即可。

文件的读写操作

文件的读操作是指通过程序从外部存储介质存储的文件中读出数据的过程。程序调用一次相应的读函数,文件的读指针会自动移到下一次读的位置。文件的写操作是指通过程序将数据写入到外部存储介质存储的文件中的过程。程序每调用用一次相应的写函数,

文件的写指针将自动移到下一次写的位置上。

1.文件的读函数
   下面将依次介绍fgetc()函数、fgets()fscanf()函数和fread函数

1)fgetc()函数(字符的读操作)

函数原型为:
int fgetc(FILE  *fp); 
功能:从文件指针fp指定的文件中读出一一个字符。操作成功返回该字符,操作失败返回EOF(EOF值为-1,也是文件的结束标志)

注意:指向的当前量读出一个字符

例:编写程序,实现将D盘上文件file.txt的内容显示在屏幕上。

#include<stdio.h>
void main()
{
    FILE *fP;
    char ch;
    if((fp=fopen ("D:\\file.txt","r"))==NULL)    //只读的方式打开指定文件
	{ prin£(” cannot open the file\n");
       exit (0);
    }
    ch=getc(fp);               //从文件读出一个字符存放到变量ch中
    while (ch!=EOF)            //EOF是文件结束标志,此处作为循环语句的结束标志
    {
	  putchar (ch) ;         //输出变量ch的值到屏幕上
	  ch=getc(fp);          //从文件中读出一个字符保存在变量ch中
    }
    fclose (fp);    //关闭打开的文件
}


如果用上述方法处理二进制文件就有可能出错,因为程序中利用. EOF作为循环控制条件,EOF的值是“-1”,文本文件中不会有“-1”,而二进制文件中可以出现“-1”,但文件并没有结束,此时就会出现文件没结束但被判断结束的后果。所以,在对二进制文件做读操作时,采用feof(fp)函数,判断文件是否结束,该函数也可以用于判断文本文件是否结束,如果文件结束,feof()函数返回1, 否则,返回0值。
因此, 例93程序中的循环语句部分做如下修改,程序将不仅适用于对文本文件的读操作,同样也适用于对一进制文件的读操作。
/*若 文件没有结束,则函数feof(fp)的返回值时0,!(feof(fp)为1 (真),循环继续执行*/

while(! (feof(fp)))

{putchar (ch);
ch=getc{fp);

}

  2) fgets()函数(字符串的读操作)

函数原型为:

 

      char *fgets(char *string,int n,FILE *fp);

      功能:从文件指针fp 所指向的文件中,读“一行”或“n-1”个字符到字符串string中,当遇到“换行符”或已读出“n-1”个字符时,停止读操作,并在字符串string的最后加上一个字符串结束标志”\0,操作成功,返回字符串string的首地址。若读到文件尾或出错,则返回空指针NULL.需要注意的是,之所以是读出“n-1”个字符,是需要留有一位放置字符串的结束标志"\0'。此外,遇到换行符时,读操作结束,但将保留换行符,即换行符被读出保存在字符串string中。

      3) fscanf()函数(格式化的读操作)

函数原型为:

      int fscanf (FILE *fp, char format, [argument, .])

      功能:从文件指针fp所指向的文件中,按format 规定的格式把数据读入argument等数据变量的地址中。其中format参数的格式与scanf()函数中的控制格式是相同的。实际上fscanf()函数和scanf()函数在用法上基本相同,区别在于scantO函数从输大设备(例如键盘)读入数据,而fscanfO函数从文件中读入数据。

      例如,将fp指向的文件的数据送入a和b中,语句如下:

      fscanf (fp, "%d, %f”,&a,&b);

将文件中当前指针位置的整型数据读出保存到整型变量a中,实型数据保存到实型变量b中。使用fscanf()函数时,要注意格式说明符与数据的一致性 .

      4) fread()函数(数据块的读操作)

函数原型为:

      int fread (buffer,size,count,fp);

      功能:函数用于二进制文件的读操作,从文件指针fp所指向的文件中读出count个数据项,每个数据项的字节数为sizce,存放到以buffer为首地址的缓冲区内。若操作成功,返回所读数据项的个数:若操作失败返回0.其中,size 不能是任意值,而是读出数据所属数据类型占用内存的字节数。比如,在16位控制系统下,读出的数据是int型,size 为2:是Char型,则size为1, 等等。相应地,在32位控制系统下,读出的数据是int型,size为4:是char型, 则size为2.等等。

      例如,在16位控制系统下,利用fread0)函数,从fp所指定文件中读入4个的整型数据,语句如下:

      int x[4];    //定义一个整型数组, 用于存放读出的数据,数组名x就是首地址

  fread(x,2,4,fp); //x是存放数据的首地址:整型类型size为2: 4个数据。

2.文件的写函数

      下面将依次介绍fputc0函数、fputs0函 数、fprint)函 数和fwrite)函数。

 

1) fputc()函数(字符的写操作)

函数原型为:
int fputc (char ch,FILE *fp);
功能:把单个字符ch写到文件指针fp指向的文件中。若操作成功,返回写入的字符:若出错则返回EOF。
例从键盘输入一 串字符,以*结束,并将输入的字符写到D盘file.txt 文件中。

#include <stdio.h>
void main()
{  char ch;
   FILE *fp;
   if((fp=fopen("D:\\file. txt", "w"))==NULL) //只写的方式打开指定文件! 
	{printf(" cannot open the file\n");
	 exit(0) ;
	}
   ch=getchar();  //允许键盘键入一个字符,并赋值给变量ch
   while(ch!='*')
   { 
	   fputc(ch, fp); //将ch写入到fp指向的文件中
	   ch=getchar();
   }
fclose(fp); //关闭文件
}


2) fputs()函数(字符串的写操作)

函数原型为:
int fputs(char *string,FILE *fp);
功能:将string指向的字符串写入到文件指针fp所指的文件中。若操作成功,返回0;若操作失败,返回文件结束标志EOF(值为-1)。需要注意,字符串的结束标志“\0不被写入文件。因此,为了以后读取时仍能区分开各个字符串,往往每写入一个串到文件之后,用语句“futs("\n",fp);" 在每个字符串后加一个换行符"\n',一 起存入文件中。
3) fprintf)函数(格式化的写操作)

函数原型为:
int fprintf(FIle *fp, char *format, largument],);
功能:按format规定的格式把数据写入到文件指针fp所指的文件中,其中format 参数的含义与fprint()函数是相同的。实际上,fprintf()函数和 pintf(函数在用法上基本相同,区别在于prinf()函数向控制台(例如显示屏)输出数据,而fprintf()函数向文件中输出数据。
例如:将变量x和y的值分别按%d和%f的格式输出到由fp所指定的文件中。语句如下:
int x=5;
float y=1.68;
fprintf(fp, "%d,%f,x,y);


      4) fwriteO函数(数据块的写操作)

函数原型为:

      int fwrite (buffer,size,count, tp);

      功能:函数用于二进制文件的写操作,将buter所指向的内存区域中coum个数据项,每项长度为size个字节,写入到文件指针fp所指的文件中。若操作成功,返回写入的数据块个数:出错时或遇到文件末尾时返回NULL

      例:编写程序, 实现从键盘输入10个整数,并存入D:\\file. bin文件中,再将文件中的10个数读出显示在屏幕上. (运行环境为32位控制系统) 

#include<stdio.h>
#include<stdlib.h>
void main()
{
      FILE *fp;
      int a[10],b[10],i;
      printf("请输入10个数: \n");
	  for(i=0;i<10;1++)
	      scanf ("&d",&a[i]);//输入10个整数保存在数组a中
      if((fp=fopen("D:\\file.bin" , "wb"))==NULL) //只写方式打开二进制文件
	{	 printf ("cannot open the file!"); 
		 exit (0) ;
	}
      fwrite(a,4,10,fp); //将10个整型数据写入到文件指针fp指向的文件中去
	  fclose(fp); //关闭文件
      if((fp= fopen("D:\\file.bin","rb"))=NULL) //只读方式打开二 进制文件
	 { printf("cannot open the file!");
       exit(0) ;
     }
      fread(b,4,10,fp); //从文件指针fp指向的文件中读出10个整型数据保存在数组b中
	  print£("\n文件中的10个数是: \n");
	  for(i=0;1<10;1++)
	{
      printf("sd ",b[i]); //将数组b中的数据输出,验证是否正确写入到文件中去
      fclose(fp); //关闭文件
    }
}

请输入10个数:

1 2 3 4 5 6 7 8 9 10

文件中的10个数是:

1 2 3 4  5 6 7  8 9 10


  文件的定位

   在对文件进行读写操作时,有一个指明当前读写位置的指针, 称为文件位置指针。在使用fopen函数打开一个文件时, 该指针指向文件的开头,每进行一次读写操作,位置指针自动发生变化。C语言系统也为程序员提供了可以定位文件位置指针的定位函数,从而可以解决实际读操作时可能只读取文件某一指定部分的问题。 

      1. rewind函数(位置 重置函数)

      函数原型为:

      void rewind(FILE *fp);

     

功能:使文件的读写位置指针移到文件的开头,若操作成功返回0,否则返回其他值。

 

      在实际应用中,若对某文件进行 多次读写操作后,需要重新读写该文件,可以采用关闭文件再打开文件的方式。而使用rewindO函数可以在不关闭文件的情况下将位置指针返回到文件的开头,达到重新读取文件的目的,显然这样更简单,效率更高。

      2. fseek0函数(随机定位函数)

函数原型为:

      int fseek(FILE *fp,long offset,int base);

      其中,fp 是已经打开的文件的指针,ofiset 是以字节为单位的位移量,base 指示位移量offset是以什么地方作为基点开始计算的。base 的取值如下:

      (1)SEEK SET:以文件开始计算,此时base代表的值为0。

      (2)SEEK CUR:以文件的当前位置计算,此时base代表的值为1。

      (3)SEEK END:以文件的末尾开始计算,此时base代表的值为2。

通过该函数可以对文件进行随机定位,从而保证了对文件随机读写的可能性。

3. ftel函数(定位当前位置函数)

函数原型为:

      1ong ftell(FILE *fp);

其调用形式为:

      1en=ftell(fp) //将当前位置指针的位置赋给长整型变量len

      功能:返回当前文件位置指针的位置,常用于保存当前文件指针位置。

题目:已知函调用形式为:fread(buffer,size,count,fp),其中buffer代表的是:一个指针,指向要读入的数据的存放地址。


 


 

©️2020 CSDN 皮肤主题: 编程工作室 设计师:CSDN官方博客 返回首页