有关库函数的使用,最好的建议是尽量使用系统头文件。因为头文件中包括了库函数的参数类型和返回类型的声明。
5.1 返回整数的getchar的函数
#include <stdio.h>
main()
{
char c;
while((c=getchar())!=EOF)
putchar(c);
}
getchar函数一般的情况下返回的是标准输入文件中的下一个字符,当没有输入时,返回EOF。但由于 c 声明成了char 类型,而不是int 类型,这意味着c 不能够容纳所有的可能的字符,特别是不能容纳EOF。两种可能的结果是:(1)某些合法的输入字符在被“截断”后使得 c 的取值与EOF相同;(2)c 根本不可能取得EOF这个值;对于前一种情况,程序将在中途终止,后一种情况,程序陷入死循环。
5.2更新顺序文件
FILE *fp;
struct record rec;
……
while(fread((char )&rec,sizeof(rec),1,fp)==1)//地址&rec被转换为字符指针
{
/对rec执行某些操作/
if(/rec必须被重新写入/)
{
fseek(fp,-(long)sizeof(rec,1);//1代表从当前位置找指针,- 号代表向前
fwrite((char)&rec,sizeof(rec),1,fp);//地址&rec被转换为字符指针
fseek(fp,0L,1);//改变了文件状态,使得文件可以进行正常的读写
}
}
5.3缓冲输出和内存分配
程序输出两种方式:(1)即使处理方式;(2)先暂存起来,然后再大块写入的方式,前者往往可以造成较高的系统负担。
C语言使用库函数setbuf 实现对输出数据量的控制。如果buf 是一个大小适当的字符数组,那么 setbuf(stdout,buf);语句同时输入输出库,所有的写入到stdout 的输出都应该使用buf 作为输出缓冲区,直到buf 缓冲区被填满或者程序员直接调用 fflush ,buf缓冲区中的内容才实际的写到stdout 中。缓冲区的大小由系统头文件<stdio.h>中的BUFSIZE 定义。
#include <stdio.h>
main()
{
int c;
char buf[BUFSIZE];//这里会造成错误,局部变量会在main函数结束之后直接释放
setbuf(stdout,buf);
while((c=getchar())!=EOF)
putchar©;
}
由于所有的标准输出首先缓存在buf中,那么buf缓冲区最后一次清空,发生在main 函数结束之后,作为程序交回控制给操作系统之前C 运行时库所必需进行的清理工作的一部分,但是,此时buf字符数组已经释放了。相当于buf 内最后的内容丢失。
要避免这种情况,两种方法:(1)让缓冲数组称为静态数组,既可以显示的声明 buf 为静态的:static char buf[BUFSIZE];,也可以把buf 声明完全移到main 函数之外。(2)动态分配缓冲区,在程序中并不主动释放分配的缓冲区: char *malloc(); setbuf(stdout,malloc(BUFSIZE));这里不需要检查malloc 函数是否调用成功,应为即使失败,返回null指针,setbuf函数的第二个参数可以取值null,此时标准输出不需要进行缓存。这样依旧可以进行工作,速度较慢。
5.4库函数signal
signal库函数,作为补货异步事件的一种方式,要使用该库函数,需要在原文件中加上 #include<signal.h>,以引入相关声明。需要处理特定的signal(信号),可以这样调用signal函数:signal(signal type,handler function); 这里signal type 代表系统头文件signal.h中定义的某些常量,这些常量用来标识signal函数将要捕捉的信号的类型。这里的 handler function 是当指定的事件发生时,要加以调用的事件处理函数。