文件流

数据在文件和内存之间的传递过程,称为文件流
文件是数据源的一种,除了文件,还有数据库、网络、键盘等。数据传递到内存的过程,也是保存到C语言的变量的过程

数据流(Data Stream)

数据在数据源和程序(内存)之间传递的过程叫数据流

输入流(Input Stream)

数据从数据源到程序(内存)的过程叫输入流

输出流(Output Stream)

输出从程序(内存)到数据源的过程叫输出流

打开文件

在C语言中,操作文件前必须打开文件;所谓“打开文件”,就是让程序和文件建立连接的过程

fopen()函数

定义形式

<stdio.h>头文件中的fopen()函数可打开文件,定义如下:

  1. FILE *fopen(char *filename,char *mode);
  2. 其中,filename为包含路径的文件名,mode为打开方式。

fopen()函数的返回值

fopen()可获取文件名、文件状态、当前读写位置等文件信息,并将这些信息保存到一个FILE类型的结构体变量中,然后将该变量的地址返回

用法

  1. 示例1
  2. FILE *fp = fopen("demo.txt","r"); //定义一个FILE类型的指针,指向fopen()返回的地址
  3. 示例2
  4. FILE *fp = fopen("D:\\demo.txt","rb+"); //文件名带路径,rb+表示以二进制的方式打开,可读写

"r"表示以“只读”的方式打开当前目录下的demo.txt文件,fp指向demo.txt可直接操作该文件fp通常被称为文件指针

判断文件是否打开成功

打开文件出错时,**fopen()**会返回一个空指针**NULL**,可以通过这一点来判断文件是否打开成功。

  1. FILE *fp;
  2. if((fp = fopen("D:\\demo.txt","rb")) == NULL)
  3. {
  4. printf("Fail to open file!\n");
  5. exit(0); //退出程序
  6. }

fopen()函数的打开方式

控制读写权限的字符串(必须指明)
权限 说明
r 只读。文件必须存在,否则打开失败。
w 以“写入”方式打开文件。如果文件不存在,将创建一个新文件;如果文件已存在,将清空文件内容(相当于删除原文件,再创建一个新文件)。
a 以“追加”方式打开文件。如果文件不存在,将创建一个新文件;如果文件已存在,将写入的数据追加到文件的末尾(保留原文件内容)
r+ 以“读写”方式打开文件。文件必须存在,否则打开失败。
w+ 以“写入/更新”方式打开文件。可读写。如果文件不存在,将创建一个新文件;如果文件已存在,将清空文件内容(相当于删除原文件,再创建一个新文件)
a+ 以“追加/更新”方式打开文件。可读写。如果文件不存在,将创建一个新文件;如果文件已存在,将写入的数据追加到文件的末尾(保留原文件内容)
控制读写方式的字符串(可选)
读写方式 说明
t 以“文本文件”方式打开。默认为**“t”**
b 以“二进制文件”方式打开。

其中,读写方式不能放在读写权限的开头。即不能出现**br+**这种写法

fopen()函数中的文本方式和二进制方式

在C语言中,以二进制方式读写文件是无损的
文本方式和二进制方式并无本质上的区别,只是对于换行符的处理不同

  • Unix/Linux系统在处理文本文件时,使用**\n**作为换行符,其它数据无损读写;
  • Windows系统下,以文本方式打开文件:
    • 读取文件时,程序会将文件中所有的**\r\n**转换成字符**\n**;若文本的有效数据存在出现连续的**\r\n**,将造成数据丢失;
    • 写入数据时,程序会将**\n**转换成**\r\n**写入。若文本文件中包含**\n**,程序将自动写入**\r\n**

因此,对于Windows平台,为保险起见,需要指定文件的打开方式,对于Unix/Linux平台,则无所谓

关闭文件

定义形式

文件一旦使用完毕,应该用fclose()函数将文件关闭,以释放相关资源,避免数据丢失。定义如下:

  1. 函数定义形式:
  2. int fclose(FILE *fp);
  3. 如:
  4. fclose(fp); //关闭文件指针

文件正常关闭时,fclose()的返回值为0;返回非零数值表示关闭文件错误

以字符形式读写文件

  • 文件内部有一个位置指针,用来指向当前读写的位置,即当前读写到第几个字符
  • 在文件打开时,该指针总是指向文件的第一个字符
  • 调用一次fgetc()函数,该指针会向后移动一个字符,多次调用,可读取多个字符
  • 该指针和C语言的指针不同,仅仅是一个位置标识,由系统自动处理,对用户是隐藏的

    fgetc()字符读取函数

    定义形式

    fgetc()读取成功时,返回读取到的字符读取到文件末尾或读取失败时,返回**EOF**。 ```c int fgetc(FILE *fp);

其中,fp为文件指针。

  1. `EOF`end of file的缩写,表示文件末尾,是在`stdio.h`中定义的宏,**其值是一个负值**,通常为-1(不绝对)。
  2. <a name="N4E4w"></a>
  3. ### 用法
  4. ```c
  5. char ch;
  6. FILE *fp = fopen("D:\\demo.txt","r+");
  7. ch = fgetc(fp);

feof()函数

用来判断文件内部指针是否指向了文件末尾

  1. 定义形式:
  2. int feof(FILE *fp);

当指向文件末尾时,返回非零值,否则返回零值

ferror()函数

用来判断文件操作是否出错

  1. 定义形似:
  2. int ferror(FILE *fp);

出错时,返回非零值,否则返回零值

用法示例

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(void)
  4. {
  5. FILE *fp;
  6. char ch; //接受字符
  7. //判断文件是否存在
  8. if((fp = fopen("D:\\demo.txt","rt")) == NULL)
  9. {
  10. puts("Fail to open file!");
  11. exti(0); //退出程序
  12. }
  13. //读取文件字符
  14. while((ch = fgetc(fp)) != EOF)
  15. {
  16. putchar(ch);
  17. }
  18. putchar('\n');
  19. if(ferror(fp))
  20. {
  21. puts("文件读取出错");
  22. }
  23. else
  24. {
  25. puts("文件读取成功");
  26. }
  27. fclose(fp); //关闭文件
  28. return 0;
  29. }

fputc()字符写入函数

定义形式

向指定的文件中写入一个字符

  1. int fputc(int ch,FILE *fp); //ch为写入的字符

写入成功时,返回写入的字符,失败时,返回**EOF**
每写入一个字符,文件内部位置指针向后移动一个字节

用法

  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. int main(void)
  4. {
  5. FILE *fp;
  6. char ch;
  7. //判断文件是否打开成功
  8. if((fp = fopen("D:\\demo.txt","wt+")) == NULL)
  9. {
  10. puts("Fail to open file!\n");
  11. exit(0);
  12. }
  13. printf("Input a string :\n");
  14. //每次从键盘读取一个字符并写入文件
  15. while((ch = getchar()) != '\n')
  16. {
  17. fputc(ch,fp);
  18. }
  19. fclose(fp);
  20. return 0;
  21. }