(十五)输入输出函数
就C程序而言,所有的IO操作只是简单地从程序移进或移出字节的事情。这种字节流便被称为流。
绝大多数流是完全缓冲的,“读取”和“写入”实际上是从一块被称为缓冲区的内存区域来回复制数据。
流分为两种类型,文本流和二进制流。
文件
stdio.h所包含的声明之一就是FILE结构。FILE是一个数据结构,用于访问一个流。如果你同时激活了几个流,每个流都有一个相应的FILE与它关联。
对于每个ANSI C程序,运行时系统必须提供至少三个流——标准输入、标准输出、标准错误。这些流的名字分别为stdin、stdout、stderr,它们都是一个指向FILE结构的指针。
为错误信息准备一个不同的流意味着,即使标准输出重定向到其他地方,错误信息仍将出现在屏幕或其他缺省的输出设备上。
流IO总览
1、程序为必须同时处于活动状态的每个文件声明一个指针变量,其类型为FILE *。这个指针指向这个FILE结构,当它处于活动状态时由流使用。
2、流通过调用fopen函数打开。为了打开一个流,必须指定需要访问的文件或设备以及它们的访问方式(读、写、既读又写)。fopen和操作系统验证文件或设备确实存在并初始化FILE结构。
3、根据需要对该文件进行读取或写入。
4、最后,调用fclose函数关闭流。关闭一个流可以防止与它相关联的文件被再次访问,保证任何存储于缓冲区的数据被正确地写到文件中,并且释放FILE结构使它可以用于另外的文件。
标准流的IO更为简单,因为它们并不需要打开或关闭。
IO函数以三种基本的形式处理数据:单个字符、文本行或二进制数据。对于每种形式,都有一组特定的函数对它们进行处理。
数据类型 | 输入 | 输出 | 描述 |
---|---|---|---|
字符 | getchar | putchar | 读取(写入)单个字符 |
文本行 | gets scanf | puts printf | 文本行未格式化/格式化的输入输出 |
二进制数据 | fread | fwrite | 读取/写入二进制数据 |
家族名 | 目的 | 可用于所有的流 | 只用于stdin和stdout | 内存中的字符串 |
---|---|---|---|---|
getchar | 字符输入 | fgetc,getc | getchar | ① |
putchar | 字符输出 | fputc,putc | putchar | ① |
gets | 文本行输入 | fgets | gets | ② |
puts | 文本行输出 | fputs | puts | ② |
scanf | 格式化输入 | fscanf | scanf | sscanf |
printf | 格式化输出 | fprintf | printf | sprintf |
①:对指针使用下标引用或间接访问操作从内存获得/写入一个字符
②:使用strcpy函数从内存读取/写入文本行
打开流
FILE *fopen(char const *name, char const *mode);
name是希望打开的文件或设备名字。mode参数提示流的访问方式和类型:
类型 | 读取 | 写入 | 添加 |
---|---|---|---|
文本 | “r” | “w” | “a” |
二进制 | “rb” | “wb” | “ab” |
FILE *freopen(char const *filename, char const *mode, FILE *stream);
最后一个参数是需要打开的流。这个函数试图关闭这个流,然后用指定的文件和模式重新打开这个流。如果打开失败,函数返回一个NULL值。如果打开成功,函数就返回它的第3个参数值。
关闭流
int fclose(FILE *f);
对于输出流,fclose函数在文件关闭之前刷新缓冲区。如果它执行成功,fclose返回零值,否则返回EOF。