1.文件的打开和关闭
1.1 什么是文件指针?
每个被使用的文件都在内存中开辟了一个相应的文件信息区,用来存放文件的相关信息(如文件的名
字,文件状态及文件当前的位置等)。这些信息是保存在一个结构体变量中的。该结构体类型是有系统
声明的,取名FILE.
假如:我们要操作一个文件,名为text.txt ,首先要打开文件,打开文件的同时,操作系统会自动为该文件创建一个文件信息区,专门用来记录该文件的信息。
文件信息区的每一个信息与text.txt的信息是一一对应的。而该文件信息区名为struct _iobuf,又被重命名为 FILE 。
所以FILE其实就是文件信息区。
每当打开一个文件的时候,系统会根据文件的情况自动创建一个FILE结构的变量,并填充其中的信息,使用者不必关心细节。
一般都是通过一个FILE的指针来维护这个FILE结构的变量,这样使用起来更加方便。
下面我们可以创建一个FILE*的指针变量:
FILE* pf; 文件指针变量
通过该文件指针变量,我们就可以读写文件中的信息。
文件在读写之前,需要打开文件
//打开文件 FILE * fopen ( const char * filename, const char * mode );
读写文件完成后,需要关闭文件:
//关闭文件 int fclose ( FILE * stream );
文件的打开方式如下:
举个例子:
#include <stdio.h> int main () { //打开文件 FILE* pFile = fopen ("text.txt","w"); //文件操作 if (pFile!=NULL) { fputs ("fopen",pFile); //关闭文件 fclose (pFile); } return 0; }
该段代码的意思是:打开一个文件叫text.txt,以写的形式打开。意味着向文件中写入信息。具体是怎么写的,下面会讲到。
写完信息后关闭文件,fclose(pFile),pFile就是一个文件指针。
文件指针就是用来操作文件的,假如我们需要对文件进行写入的操作,就使用文件指针打开该文件并定义"写"的操作。
2.文件操作函数
2.1 fgetc函数和fputc函数
fgetc函数和fputc函数是针对字符的输入输出的。
int fgetc(FILE* stream); //从流中读取字符,返回读到的ascii码值
流是什么呢?可以把流理解成水流,水流到尽头,就是一个蓄水池。一个蓄水池就相当于一个存储大量文件的区域。文件也类似,从流中(文件信息区)中读取文件,fgetc返回读到的ascii码值。
int fputc(int character, FILE* stream); //把字符character 写入流中
fputc是将一个字符写入文件中。一次写入一个字符,返回成功写入的字符的个数。
举个例子:
int main() { FILE* pf =fopen("text.txt", "w"); if (pf == NULL) { perror("fopen"); return 0; } //写入字符 char ch = 0; for (ch = 'a'; ch <= 'z'; ch++) { fputc(ch, pf); } fclose(pf); pf = NULL; return 0; }
先打开text.txt文件,如果不存在该文件,则会新建一个文件("w"写入的形式会新建一个文件,但是以"r"的形式打开文件,如果文件不存在,会读取文件失败,返回NULL)
然后向文件中写入a~z个字母。
运行成功,成功写入文件:
写入成功,现在向文件中读取数据
int main() { FILE* pf = fopen("text.txt", "r"); if (pf == NULL) { perror("fopen"); return 0; } //写入字符 char ch = 0; for (ch = 'a'; ch <= 'z'; ch++) { int ch = fgetc(pf); printf("%c ", ch); } fclose(pf); pf = NULL; return 0; }
读取成功,如下图:
总结:fgetc函数是向文件指针pf(或者其他名字,由你来定)一次读取一个字符,读取完第一个字符后,指针自动跳到下一个字符。
fputc函数是向pf指向的指针一次写入一个字符。
2.2 fgets函数和fputs函数
int fputs(const char* str, FILE* stream); 向流中写入一行数据,一次性写一行
举个例子:
int main() { FILE* pf = fopen("text.txt", "w"); if (pf == NULL) { perror("fopen"); return 0; } fputs("Hello World","w"); fclose(pf); pf = NULL; return 0; }
写入成功。
注意:打开文件进行写入操作时,上一次写入的数据将会被清除。
接下来向从文件中读取数据:
int main() { FILE* pf = fopen("text.txt", "r"); if (pf == NULL) { perror("fopen"); return 0; } //读文件,一次读一行 char buf[20]; fgets(buf, 10, pf); // 读10个字节,相当于读9个,最后一个字节留着放\0 printf("%s\n", buf); fclose(pf); pf = NULL; return 0; }
注意:当我们读取10个字节时,实际上打印出来只打印前面9个字节的内容,还有一个字节是被用来留着放\0的。
还有一种情况,假如我们需要读取20个字节的数据,然而第一行不足20个字节,fgets读完所有的数据后,即使不够20个字节,就不会再读取了,就停止了。不会跳到第二行继续读。 更说明fges是一次只读取一行。