第七章 文件
- 7.1 C语言文件的概念
- 7.1.1 文件的概念
- 在此之前,所有的输入和输出只涉及到键盘和显示器。在运行C程序时,我们通过键盘输入数据并借助显示器把程序的运算结果显示出来。但是,计算机作为一种先进的数据处理工具,它所面对的数据信息量十分庞大,仅依赖于键盘输入和显示输出等方式是远远不够的。通常,解决的办法是将这些数据记录在某些介质上,利用这些介质的存储特性,携带数据或长久地保存数据。这种记录在外部介质上的数据集合称为“文件”。
- 在程序运行之前,常常需要将一些数据(运行的最终结果或中间数据)输出到磁盘上保存起来,以后需要时再从磁盘中输入到计算机中,这就需要用到磁盘文件。
- C程序把文件分为ASCII文件和二进制文件。ASCII文件又称文本文件,本章我们仅讨论通过C程序的输入输出所涉及的、存储在外部介质上的文件,这类文件通常称为“数据文件”,并以磁盘作为存储介质。
- 在程序中,当调用输入函数从外部文件中输入数据赋给程序中的变量时,这种操作称为“输入”或“读”;当调用输出函数把程序中的变量的值输出到外部文件中时,这种操作称为“输出”或“写”。
- 在C语言中,文件是一个字节流或二进制流,也就是说,对于输入输出的数据都按“数据流”的形式进行处理。输出时,系统不添加任何信息;输入时,逐一读入数据,直到遇到文件结束标志。C程序中的输入输出文件,都以数据流的形式存储在介质上。
- 文件输入输出方式也称“存取方式”。C语言中,文件有两种存取方式:顺序存取和直接存取。
- 顺序存取文件的特点是:每当“打开“文件进行读或写操作时,总是从文件的开头开始,从头到尾顺序地读写。
- 直接存取文件的特点是:可以通过C语言的库函数去指定开始读(写)的字节号,然后直接对此位置上的数据进行读(写)操作。
- 7.1.2 文件类型指针
- 文件指针
- 当使用一个文件时,系统就为该文件在内存中开辟一个区域来存放该文件的相关信息,如该文件的名字、状态、位置等,这些信息都被保存到由系统定义的名为FILE的一个结构体类型的变量中。可以用该结构体类型来定义文件类型的指针变量,
- 一般形式为:
- FILE*fp;
- fp是一个指向FILE结构体类型的指针变量。
- FILE*fp;
- 文件指针
- 7.1.1 文件的概念
- 7.2 文件的打开与关闭
- 概念
- 对文件进行读写操作时,首先要解决的问题是如何把程序中读写的文件与磁盘上的实际数据文件联系起来,接着就应该“打开”文件,在使用结束之后关闭文件。
- 7.2.1 fopen()函数
- ANSI C规定了标准输入输出函数库,用fopen()函数来打开一个文件,其一般的调用方式为:
- FILE*fp;
- fp=fopen(文件名,使用文件方式);
- 例如:
- FILE*fp;
- fp=fopen(“file1”,“r”);
- 注意
- fopen()函数中要有两个字符串作为参数。第一个字符串中包含了进行读写操作的文件名,即用来指定所要打开的文件。本例中,指定文件名为file1。第二个字符串中指定了文件的使用方式,用户可以根据这个参数来指定对文件的使用意图。本例中,使用文件的方式为“r”读入方式。
- 若函数调用成功,函数返回一个FILE类型的指针,赋给文件指针变量fp,从而把指针fp与文件“file1“联系起来。也就是说,调用函数后,fp指向了文件“file1”。
- 使用文件方式
- (1)“r“方式打开文件时,只能进行读操作,而不能进行写或其他操作,而且该文件必须已经存在。
- (2)“w“方式打开文件时,只能对该文件进行写(即输出文件)操作,而不能用来向计算机中进行输入操作。如果原来不存在该文件,则在打开时新建一个以指定的名字命名的文件。如果已经存在一个以该文件名命名的文件,则将从文件的起始位置开始写起,文件原有内容将全部被删除。
- (3)以“a“方式打开文件时,是向该文件的后面添加数据。如果指定的文件名不存在,系统将用在fopen()函数调用中指定的文件名建立一个新文件;如果指定文件已存在,则文件中原有的内容将保存,新的数据写在原有内容之后。
- (4)以“r+“、“w+“、“a+“方式打开文件时,既可以进行读操作,同时也可以进行写操作。用“r+“方式时打开的文件必须已经存在,以便能向计算机输入数据。用“w+“方式则新建一个文件,先向此文件写数据,然后可以读此文件中的数据。用“a+“方式打开文件时,原来的文件不被删除,只是在文件尾部添加新的数据。
- (5)“wb+“功能与“w+“相同,只是在随后的读和写时,可以由位置函数设置读和写的起始位置。
- (6)“ab+“功能与“a+“相同,只是在文件尾部添加新的数据之后,可以由位置函数设置开始读的起始位置。
- 例如:
- ANSI C规定了标准输入输出函数库,用fopen()函数来打开一个文件,其一般的调用方式为:
- 7.2.2 fclose()函数
- 在对一个文件进行读写操作后应该关闭它,以防止它再被误用。
- fclose()函数的功能就是关闭文件,其一般形式为:
- fclose(文件指针);
- 例如:
- fclose(fp);
- 例如:
- fclose(文件指针);
- 概念
- 7.3 文件的读写
- 概念
- 文件打开之后,就可以对它进行读写了。
- fputc()函数和fgetc()函数(putc()函数和getc()函数)
- 7.3.1 fputc()函数
- 该函数的功能是把一个字符写到磁盘文件上去,其一般调用形式为:
- fputc(c,fp);
- 其中c是要输出的字符,fp是文件指针。
- 7.3.2 fgetc()函数
- 该函数的功能是从指定的文件中读入一个字符,该文件必须是以读或读写方式打开的。其一般调用形式为:
- c=fgetc(fp);
- fp为文件类型指针变量,fgetc()函数带回一个字符赋给c。
- 7.3.3 fread()函数和fwrite()函数
- 当要求一次性读写一组数据时,例如,一个实数或一个结构体变量的值,就可以使用fread()函数和fwrite()函数,它们的一般调用形式为:
- fread(buffer,size,count,fp);
- fwrite(buffer,size,count,fp);
- 其中,buffer代表的是一个指针变量;size代表的是要读写的字节数;count用来指定每读写一次,输入或输出数据块的个数(每个数据块具有size个字节);fp是文件类型指针。
- 7.3.4 fscanf()函数和fprintf()函数
- fscanf()函数和fprintf()函数都是格式化的读写函数,与scanf()和printf()函数作用相似,但fscanf()函数和fprintf()函数读写对象是磁盘文件上的数据。它们的一般形式如下:
- fscanf(文件指针,格式字符串,输入列表);
- fprintf(文件指针,格式字符串,输出列表);
- 7.3.5 fgets()函数
- fgets()函数用来从文件中读入字符串,调用形式如下:
- fgets(str,n,fp);
- 其中str是存放字符串的起始地址,n是一个整型变量,fp是文件指针。该函数的功能是从fp指向的文件中读入n-1个字符放入以str为起始的地址单元内。如果在读完n-1个字符之前读到换行符或EOF,则结束本次读入操作。
- 7.3.6 fputs()函数
- fputs()函数是用来把字符串输出到文件中,调用形式如下:
- fputs(str,fp);
- 其中str是要输出的字符;fp是文件指针,字符串末尾的′ ′不输出。
- 概念
- 7.4 文件的定位
- 概念
- “文件位置指针“和“文件指针“是两个完全不同的概念。文件指针是在程序中定义的FILE类型的变量,通过fopen()函数,把文件指针和某个文件建立联系。C语言程序通过文件指针实现对文件的各种操作。文件位置指针只是一个形象化的概念,我们将用文件位置指针来表示当前读或写的数据在文件中的位置。当打开文件时,可以认为文件位置指针总是指向文件的开头,即第一个数据之前。当文件位置指针指向文件末尾时,表示文件结束。
- 7.4.1 rewind()函数
- rewind()函数的调用形式如下:
- rewind(fp);
- 该函数的功能是使文件的位置指针重新返回到文件的开头,其中fp为文件指针,且该函数没有返回值。
- 7.4.2 fseek()函数和随机读写
- 如果控制好文件的位置指针,就可以对流式文件进行顺序读写和随机读写。fseek()函数的功能就是移动文件位置指针到指定的位置,其一般的调用形式为:
- fseek(文件类型指针,位移量,起始点)
- “位移量“指以“起始点“为基点,向前移动的字节数。C语言要求位移量是long型数据,并规定在数字的末尾加一个字母L。
- 7.4.3 ftell()函数
- ftell()函数的作用是得到流式文件中的当前位置,用相对于文件开头的位移量来表示。如果ftell()函数返回值为-1L,表示出错。
- 7.4.4 传给main()函数的参数
- 以前的学习中,我们在编写main()函数时,其后一对圆括号是空的,没有参数。其实,在支持C语言的环境中,可以在运行C程序时,通过运行C程序的命令行,把参数传给C程序。main()函数通常可用两个参数,例如:
- main(intargc ,char **argv)
- {}
- 其中argc和argv是两个参数名,可由用户自己命名。但是,它们的类型却是固定的,第一个参数argc必须是整型;第二个参数argv是一个指向字符型的指针数组的指针,这个字符型指针数组的每个指针都指向一个字符串。因此,第二个参数argv还可直接定义成基类型为字符型的指针数组:
- char*argv[];
- 当我们对包含以上主函数的、名为myc的文件进行编译连接,生成名为myc.exe的可执行文件后,即可在操作系统提示符下输入以下命令执行该程序:
- myc
- 这就称为命令行,myc即为执行程序的命令。这时argc中的值为1,argv[0]中将存放字符串“myc“的首地址,即指向字符串“myc“。
- 概念