流
- 流(Stream): C语言中,流表示==任意输入的源或任意输出的目的地==。
- 流经常表示存储在不同介质的==文件==,也经常和==不存储文件的设备(如网络端口,打印机)==关联。
<stido.h>
中的函数可以处理各种形式的流。
文件指针
- 文件指针(file pointer):C程序中==对流的访问是通过文件指针来实现的==。
- 文件指针的类型:
FILE *
- FILE类型是在
<stdio.h>
中声明的。
- 示例:
FILE *fp1;
标准流和重定向
<stdio.h>
提供了3个标准流:
stdin
:标准输入流,默认是键盘。
stdout
:标准输出流,默认是屏幕。
stderr
:标准错误,默认是屏幕。
- 标准流的特性:
- 这三个标准流==可以直接使用,不需要对其进行声明,也不用打开或者关闭==。
- stdin,stdout,stderr是三个==文件指针==。
- 重定向:
- 操作系统通过==重定向的操作改变标准流的默认含义==。
- 输出重定向:使stdin流表示文件,而不是键盘,通过在命令行中使用
<
实现,如:demo <in.dat
,运行demo程序时从in.dat文件中获取数据。
- 输出重定向:使stdout流表示文件,而不是屏幕,通过在命令行中使用
>
实现,如:demo >out.dat
,运行demo程序时输出到out.dat文件中。
文本文件和二进制文件
<stdio.h>
支持文本文件和二进制文件。
- 文本文件(text file):
- 在文本文件中,==字节表示字符==;
- 文本文件分为若干行:
- 文本文件的每一行通常==以一两个特殊字符结尾==;
- windows系统是以==回车符
\x0d
和回行符\x0a
==结尾;
- unix操作系统是以==一个单独的回行符
\x0a
==结尾。
- 文本文件末尾可以包含一个特殊的文件末尾标识符:
- 文件末尾标识==不是必须的,但一旦存在,就标志着文件的结束==。
- 二进制文件:
- 在二进制文件中,==字节可以表示很多类型的数据==。
- 二进制文件==不分行,没有行末标记和文件末尾标记==。
文件操作
<stdio.h>
提供了一系列的文件操作,包括打开文件,关闭文件,改变文件的缓冲方式,删除文件以及重命名文件等。
打开文件
fopen()
函数:
- 将文件打开并用作==流==;
- 原型:
FILE *fopen(const char *filename, const char *mode)
- filename:要打开文件的文件名(可能包含文件的==路径信息==。)
- 路径:在windows系统中的路径中含有
\
,会被C语言识别为转移字符,而导致错误。常用\\
或者/
来替换路径中的\
。
- mode:==模式字符串==,用来指定打算对文件执行的操作。对==文本文件和对二进制文件的模式字符串是不一样的==。
- 对文本文件的六种模式字符串:
"r"
:打开文件用于读;
"w"
:打开文件用于写(文件不需要存在)
"a"
:打开文件用于追加(文件不需要存在)
"r+"
":打开文件用于==读和写,从文件头开始==;
"w+"
:打开文件用于==读和写(如果文件存在就清空)==;
"a+"
:打开文件用于==读和写(如果文件存在就追加)==。
- 对二进制文件也有六种模式字符串,只需要在文件文件的基础上==加上b==即可。
- 返回值:
- fopen函数的返回值是一个==文件指针==;
- 当无法代开文件时,会==返回一个空指针==。
关闭文件
flclose()
函数:
- 关闭不再使用的文件。
- 原型:
int fclose(FILE *stream)
- 参数:
- ==必须是来自fopen函数或者freopen函数的文件指针==;
- 返回值:
- 如果成功关闭的文件,返回==0==;
- 如果失败,返回==EOF==(EOP是
<stdio.h>
中定义的宏)
为打开的流附加文件
freopen()
函数:
- 该函数为已经打开的流附加上一个不同的文件。
- 原型:
FILE *freopen(const char *filename, const char *mode, FILE *stream)
- 参数:
- 前两个参数同fopen一样;
- 第三个参数是一个文件指针,指向一个已经打开了的流。
- 返回值:
- 正常的返回值是它的第三个参数,一个文件指针;
- 如果无法打开新文件,返回==空指针==。
从命令行获取文件名
- 执行程序时,可以通过将==文件名放入命令行的方式为程序提供文件名==。
- 示例:命令
demo demo1.txt demo2.txt
,其中demo是程序名,剩下的是文件名。在C语言中argv[1]
指向字符串demo1.txt
,argv[2]
指向字符串demo2.txt
临时文件
- 临时文件:==只在程序运行时==存在的文件。
<stdio.h>
提供了两个函数来处理临时文件。
tmpfile()
:
- tmpfile函数用于==创建临时文件==(用wb+模式打开),这个临时文件在==关闭它或者程序终止==时消失。
- 原型:
FILE *tmpfile(void)
- 返回值:
- 如果创建文件成功,会返回==文件指针==;
- 如果创建失败,返回==空指针==。
- 特点:
- 无法知道tmpfile创建的临时文件的==文件名==;
- 无法使用tmpfile创建的文件成为==永久性的==。
tmpnam()
:
- tmpname函数为临时文件==产生名字==。
- 原型:
char *tmpnam(char *s);
- 参数:
- 如果参数是一个空指针,tmpnam会==将生成的文件名存储到一个静态字符数组变量中去,并且返回指向这个变量的指针==;
- 传递给tmpnam的参数应该是一个==字符数组==,tmpnam会将文件名存储到这个字符数组中去,并==返回指向这个数组第一个元素的指针==。
- tmpnam函数常与fopen函数配合生成具有名字的临时文件。
文件缓冲
- 使用文件缓冲的原因:向外存写入或者读出数据都是==相对较慢==的操作。
- 缓冲(buffering):将写入流或者输入流中的数据,先写入==缓冲区==,最后再将缓冲区的内容写入实际的设备。
<stdio.h>
中的缓冲函数,会在缓冲有用时==自动进行缓冲操作==,缓冲是在后台发生的。
fflush
函数:
- 调用fflush函数,可以按照我们希望的频率==将缓冲区的内容写到相应设备上去==。
- 原型:
int fflush(FILE *stream)
- 参数:
- 如果传递的是一个==文件指针==,则将与该文件指针相关联的文件的缓冲区内容写到实际设备。
- 如果传递的是一个==空指针==,则将所有缓冲区内容写到实际设备上去。
- 返回值;
- 调用成功,==返回0==;
- 调用失败,==返回EOF==。
setvbuf
函数:
- 改变缓冲流的方法,并且允许控制缓冲区的大小和位置。
- 原型:
int setvbuf(FILE *stream, char *buf, int mode, size_t size);
- 参数:
stream
:需要改变缓冲方式的流;
buf
:期望的==缓冲区的地址==;
- 如果实参为空指针,则会==创建一个指定大小的缓冲区==。
mode
:期望的缓冲类型,只能为==下列三个宏==:
_IOFBF
:==满缓冲==,当缓冲区为空时,从流读入数据;当缓冲区满时,向流写入数据;
_IOLBF
:==行缓冲==,每次从流读入一行数据或者向流写入一行数据;
_IONBF
:==无缓冲==,直接从流读入数据或者直接向流写入数据,而没有缓冲区。
size
:缓冲区内==字节的数量==。
- 返回值:
- 调用成功,==返回0==;
- 调用失败,==返回非零值==。
setbuf
函数:
文件删除与重命名
remove
函数:
- 用于删除文件;
- 原型:
int remove(const char *filename)
- 参数:
- 返回值:
- 要删除的文件需要关闭。
rename
函数:
- 改变文件的名字;
- 原型:
int rename(const char *old, const char *new)
- 参数:
- 返回值:
- 注意: