错误报告

perror 函数以一种简单,统一的方式报告错误.

perror 函数简化用户报告一些特定错误的过程, 它的原型定义与 stdio.h:

void perror(char const *message);

如果 message 不是 NULL 并且指向一个非空的字符串, perror 函数就打印出这个字符串, 后面跟一个分好和空格, 然后打印出一条用于解释 errno 当前错误代码的信息.

终止执行

exit 函数用于终止一个程序执行. 原型定义于 stdlib.h:

void exit(int status);

status 参数是返回给操作系统的, 用于提示程序是否正常完成.

预定义符号 EXIT_SUCCESS 和 EXIT_FAILURE 分别提示程序的终止是 成功还是失败.

标准 I/O 函数库

ANSI I/O 概念

头文件 stdio.h 包含了与 ANSI 函数库的 I/O 部分有关的声明.

C 所有的 I/O 操作只是简单地从程序移进或移出. 这种字节流便称为流(stream)

绝大多数流是完全缓冲的(fully bufferd). 读取和写入实际上是从一块被称为 缓冲区(buffer)的内存区域来回复制数据.从内存中来回复制数据是非常快的.

御用输出流的缓冲区只有当它写满时才会被刷新(flush, 物理写入)到设备文件中.

流分为两种, 文本(text)流和二进制(binary)流

文件

stdio.h 包含 FILE 结构, FILE 是一个数据结构, 用于访问一个流.

对于每个 ANSI C 程序, 运行时系统必须提供至少三个流----标准输入(standard input), 标准输出(standard output) 和 标准错误 (standard error). 这些流的名称分别为 stdin, stdout 和 stderr. 他们都是指向 FILE 结构的指针.

标准 I/O 常量

EOF 提示到达了文件尾. EOF 所选择的实际值比一个字符要多几位, 这是为了避免 二进制值被错误的解释为 EOF.

FOPEN_MAX 存储了保证能够同时打开的文件数目.

FILENAME_MAX 用于提示编译器所支持的最长合法文件名.

流 I/O 总览

  1. 程序为必须同时处于活动状态的文革文件声明一个指针变量, 类型为 FILE *.
  2. 流通过 fopen 函数打开.
  3. 根据需要对文件进行读取或吸入
  4. fclose 函数关闭流
数据类型 输入 输出 描述
字符 getchar putchar 读取(写入)单个字符
文本行 gets/scanf puts/printf 文本行末行格式化输入(输出)/格式化输入(输出)
二进制数据 fread fwrite 读取(写入)二进制数据
  1. 只用于 stdin 或 stdout
  2. 随作为参数的流使用
  3. 使用内存中的字符而不是流

输出/输出函数家族

家族名 目的 可用于所有流 只用于 stdin 和 stdout 内存中的字符串
getcahr 字符输入 fgetc, getc getchar 1
putchar 字符输出 fputc, putc putchar 1
gets 文本行输入 fgets gets 2
puts 文本行输出 fputs puts 2
scanf 格式化输入 fscanf scanf sscanf
printf 格式化输出 fprintf printf sprintf
  1. 对指针使用下标引用或间接操作获得一个字符(或向内存吸入一个字符)
  2. 使用 strcpy 函数从内存读取文本行(或向内存写入文本行)

打开流

fopen 函数打开一个特定文件, 并把一个流和这个文件相关联:

FILE *fopen(char const *name, char const *mode);

两个参数都是字符串. name 是你希望打开的文件或这杯名字.

mode 参数提示流打开的方式: "r", "rb", "w", "wb", "a", "ab"

在 mode 中添加了 "a+" 表示该文件用于更新, 并且流同时允许读和写.

fopen 函数执行失败返回一个 NULL 指针.

freopen 函数用于打开(或重新打开)一个特定的文件流:

FILE *freopen(char const *filename, char const *mode, FILE *stream);

关闭流

fclose 用于关闭流:

int fclose(FILE *f);

字符 I/O

字符流输入相关函数原型:

int fgetc(FILE *stream);
int getc(FILE *stream);
int getchar(void);

字符流输出

int fputc(int character, FILE *stream);
int putc(int character, FILE *stream);
int putchar(int character);

fgetc 和 fputc 都是真正的函数, 但是 getc, putc, getchar, putchar 都是通过 #define 指令定义的宏.

ungetc 函数可以撤销字符输入流:

int ungetc(int character, FILE *stream)

未格式化的行 I/O

char *fgets(char *buffer, int buffer_size, FILE *stream);
char *gets(char *buffer);

int fputs(char const *buffer, FILE *stream);
int puts(char const *buffer);

格式化的行 I/O

scanf 家族

int fscanf(FILE *stream, char const *format, ...);
int scanf(char const *format, ...);
int sscanf(char const *string, char const *format);

scanf 格式代码

  1. 空白字符 ---- 在处理过程中被忽略
  2. 格式代码 ---- 指定函数如何解释接下来输入的字符
  3. 其他字符 ---- 下一个输入字符必须与它匹配. 如不匹配, 函数不在读取直接返回.

printf 家族

int fprintf(FILE *stream, char const *format, ...);
int printf(char const *format, ...);
int sprintf(char *buffer, char const *format, ...);

二进制 I/O

size_t fread(void *buffer, size_t size, size_t count, FILE *stream);
size_t fwrite(void *buffer, size_T size, size_t count, FILE *stream);

buffer 是一个指向用于保存数据内存位置的指针, size 是缓冲区中每个元素的 字节数, count 是读取或写入的元素数. stream 就是数据读取或写入的流.

刷新和等位函数

fflush 强制输出流的缓冲区内的数据进行物理写入.

int fflush(FILE *stream);

ftell函数用于返回流的当前位置, fseek 用于定位流的位置

long ftell(FILE *stream);
int fseek(FILE *stream, long offset, int from);
fseek 函数允许你在一个流中定位, 这个操作将改变下一个读取或写入操作的位置.

fseek 第2和第3个参数标识文件中需要定位的位置.

如果 from 是 你将定位到..
SEEK_SET 从流的起始位置起 offset 个字节, offset 必须是一个非负值
SEEK_CUR 从流的当前位置起 offset 个字节, offset 的值可正可负
SEEK_END 从流的尾部位置起 offset 个字节, offset 的值可正可负. 正直则定位到文件尾的后面.

改变缓冲方式

下面两个函数可以用于对缓冲方式进行修改. 这两个函数只有当指定的流被 打开还没有在它上面执行任何其他操作前才能被调用

void setbuf(FILE *stream, char *buf);
int setvbuf(FILE *stream, char *buf, int mode, size_t size);

setbuf 设置了另一个数组, 用于对流进行缓冲. 这个数组的长度必须为 BUFSIZ. 如果用一个 NULL 参数调用这个函数, setbuf 函数将关闭流的所有缓冲方式.

setvbuf 函数更为通用. mode 参数用于指定缓冲的类型, _IOFBF 指定一个完全缓冲流, _IONBF 指定一个不缓冲的流, _IOLBUF 指定一个行缓冲流.

buf 和 size 参数用于指定需要使用的缓冲区, buf 为 NULL, size 必须为0.

流错误函数

int feof(FILE *stream);
int ferror(FILE *stream);
void clearerr(FILE *stream);

feof 判断文件是否处于末尾

ferror 函数报告流的错误状态, 如有任何读/写错误函数就返回真

clearerr 函数对指定流的错误标识进行重置.

临时文件

FILE *tempfile(void); // 创建临时文件
char *tmpnam(char *name); // 创建命名临时文件

如果传递给 tmpnam 函数的的参数为NULL, 那么这个函数便返回一个指向 静态数组的指针, 该数组包含了被创建的文件名.

只要调用次数不超过 TMP_MAX 次, tmpname 函数每次调用时都能禅城一个新的不同的名字.

文件操纵函数

int remove(char const *filename); // 删除函数
int rename(char const *oldname, char const *newname); // 从命令