有关库函数的使用,我们能给出的最好建议是尽量使用系统头文件。
5.1 返回整数的getchar函数
getchar 定义: int getchar (void);
getchar 的标准定义 是返回一个 int类型,下面的示例用 char 类型接收int类型,可能会造成内存溢出的不可预知错误
#include <stdio.h>
int main()
{
char c;
while((c=getchar()) != EOF) // getchar 返回值类型不匹配
putchar(c);
return 0;
}
5.2 更新顺序文件
为了保证与过去不能同时进行读写操作的程序的向下兼容性,一个输入操作不能随后直接紧跟一个输出操作,反之亦然;如果需要同时进行输入和输出操作,必粗在其中插入fseek 函数的调用;
FILE *fp;
fp = fopen(file,"r+");
struct record rec;
// ...
while(fread( (char *)&rec, sizeof(rec), 1, fp) == 1)
{
if (/*rec 必须被重新写入*/)
{
fseek(fp,-(long)sizeof(rec),1); // 需要先 fseek
fwrite((char *)&rev, sizeof(rev), 1, fp);
fseek(fp,0L,1); // 循环之后重新 fread
}
}
5.3 缓冲输出与内存分配
程序输出有两种方式:一种是即时处理方式,另一种是先暂存起来,然后再大块写入的方式,前者往往造成 较高的系统负担;
这种控制能力一般是通过库函数 setbuf 实现的。
static char buf[1024];
setbuf(stdout,buf);
5.4 使用errno检测错误
很多库函数,特别是那些与操作系统有关的,当执行失败时会通过一个名称为 errno 的外部变量,通知程序该函数调用失败;
因此,在调用库函数时,我们应该首先检测作为错误指示的返回值,确定程序执行已经失败(如果执行成功判断errno,可能是缓存的其它错误)。然后,再检车errno ,来搞清楚出错原因;
// 调用库函数
if (/*库函数返回失败*/)
// 检查 errno
55 库函数signal
signal 库函数,作为捕获异步事件的一种方式;
signal(signal type, handler function);
signal: 标识函数将要捕获的信号类型;
function: 当指定事件发生时,将要加以调用的事件处理函数;
#include <signal.h>
int function()
{
printf("signal error");
exit(); // 退出程序或做什么其它的操作
}
int main()
{
signal(signal type, handler function);
return 0;
}
因为异常信号的出现不可预测,所以信号非常复杂棘手,而且具有一些从本质上而言不可移植的特性;解决这个问题我们最好采取 守势,让 signal 处理函数尽可能的简单,并将他们组织在一起;