文件流
数据在文件和内存之间的传递过程,称为文件流。
文件是数据源的一种,除了文件,还有数据库、网络、键盘等。数据传递到内存的过程,也是保存到C语言的变量的过程。
数据流(Data Stream)
输入流(Input Stream)
输出流(Output Stream)
打开文件
在C语言中,操作文件前必须打开文件;所谓“打开文件”,就是让程序和文件建立连接的过程。
fopen()函数
定义形式
<stdio.h>
头文件中的fopen()
函数可打开文件,定义如下:
FILE *fopen(char *filename,char *mode);
其中,filename为包含路径的文件名,mode为打开方式。
fopen()函数的返回值
fopen()
可获取文件名、文件状态、当前读写位置等文件信息,并将这些信息保存到一个FILE类型的结构体变量中,然后将该变量的地址返回。
用法
示例1:
FILE *fp = fopen("demo.txt","r"); //定义一个FILE类型的指针,指向fopen()返回的地址
示例2:
FILE *fp = fopen("D:\\demo.txt","rb+"); //文件名带路径,rb+表示以二进制的方式打开,可读写
"r"
表示以“只读”的方式打开当前目录下的demo.txt
文件,fp
指向demo.txt
,可直接操作该文件,fp
通常被称为文件指针。
判断文件是否打开成功
打开文件出错时,**fopen()**
会返回一个空指针**NULL**
,可以通过这一点来判断文件是否打开成功。
FILE *fp;
if((fp = fopen("D:\\demo.txt","rb")) == NULL)
{
printf("Fail to open file!\n");
exit(0); //退出程序
}
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()函数将文件关闭,以释放相关资源,避免数据丢失。定义如下:
函数定义形式:
int fclose(FILE *fp);
如:
fclose(fp); //关闭文件指针
文件正常关闭时,fclose()的返回值为0;返回非零数值表示关闭文件错误。
以字符形式读写文件
- 文件内部有一个位置指针,用来指向当前读写的位置,即当前读写到第几个字符;
- 在文件打开时,该指针总是指向文件的第一个字符;
- 调用一次fgetc()函数,该指针会向后移动一个字符,多次调用,可读取多个字符;
- 该指针和C语言的指针不同,仅仅是一个位置标识,由系统自动处理,对用户是隐藏的。
fgetc()字符读取函数
定义形式
fgetc()
读取成功时,返回读取到的字符,读取到文件末尾或读取失败时,返回**EOF**
。 ```c int fgetc(FILE *fp);
其中,fp为文件指针。
`EOF`即end of file的缩写,表示文件末尾,是在`stdio.h`中定义的宏,**其值是一个负值**,通常为-1(不绝对)。
<a name="N4E4w"></a>
### 用法
```c
char ch;
FILE *fp = fopen("D:\\demo.txt","r+");
ch = fgetc(fp);
feof()函数
用来判断文件内部指针是否指向了文件末尾。
定义形式:
int feof(FILE *fp);
ferror()函数
用来判断文件操作是否出错。
定义形似:
int ferror(FILE *fp);
用法示例
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
char ch; //接受字符
//判断文件是否存在
if((fp = fopen("D:\\demo.txt","rt")) == NULL)
{
puts("Fail to open file!");
exti(0); //退出程序
}
//读取文件字符
while((ch = fgetc(fp)) != EOF)
{
putchar(ch);
}
putchar('\n');
if(ferror(fp))
{
puts("文件读取出错");
}
else
{
puts("文件读取成功");
}
fclose(fp); //关闭文件
return 0;
}
fputc()字符写入函数
定义形式
向指定的文件中写入一个字符。
int fputc(int ch,FILE *fp); //ch为写入的字符
写入成功时,返回写入的字符,失败时,返回**EOF**
。
每写入一个字符,文件内部位置指针向后移动一个字节。
用法
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
FILE *fp;
char ch;
//判断文件是否打开成功
if((fp = fopen("D:\\demo.txt","wt+")) == NULL)
{
puts("Fail to open file!\n");
exit(0);
}
printf("Input a string :\n");
//每次从键盘读取一个字符并写入文件
while((ch = getchar()) != '\n')
{
fputc(ch,fp);
}
fclose(fp);
return 0;
}