第五章 :库函数
5.1 返回整数的getchar函数
getchar 函数在一般情况下返回的是标准输入文件中的下一个字符,当没有输入时返回EOF(一个在头文件 stdio.h中被定义的值,不同于任何一个字符)。
这个程序乍一看似乎是把标准输入复制到标准输出,实则不然。
原因:在于程序中的变量c被声明为 char 类型,而不是int类型。这意味着c无法容下所有可能的字符,特别是,可能无法容下EOF。
可能会导致三种结果:①某些合法的输入字符在被“截断”后使得c的取值与EOF相同;②另一种可能是,c根本不可能取到EOF这个值。对于前一种情况,程序将在文件复制的中途终止:对于后一种情况,程序将陷入一个死循环。③编译器可能会比较getchar函数的返回值与EOF,编译器如果采取的是这种做法,上面的例子程序看上去就能够“正常”运行了。
5.2 更新顺序文件
①&rec在传入fread 和 fwrite函数时被转换为字符指针类型,sizeof(rec)被转换为长整型。
②第二个fseek函数虽然看上去什么也没做,但它改变了文件的状态,使得文件可以正常地进行读取了。
为了保持与过去不能同时进行读写操作的程序的向下兼容性,一个输入操作不能随后直接紧跟一个输出操作,反之亦然。如果要同时进行输入和输出操作,必须在其中插入fseek函数的调用。
5.3 缓冲输出与内存分配
程序输出有两种方式:一种是即时处理方式,另一种是先暂存起来,然后再大块写入的方式,前者往往造成较高的系统负担。
因此,C语言实现通常都允许程序员进行实际的写操作之前控制产生的输出数据量。
这种控制能力一般是通过库函数setbuf实现的。如果buf是一个大小适当的字符数组,那么,
setbuf (stdout,buf ) ;
语句将通知输入/输出库,所有写入到stdout的输出都应该使用buf作为输出缓冲区,直到 buf缓冲区被填满或者程序员直接调用fflush(译注:对于由写操作打开的文件,调用fflush将导致输出缓冲区的内容被实际地写入该文件),buf缓冲区中的内容才实际写入到stdout中。缓冲区的大小由系统头文件<stdio.h>中的BUFSIZ定义。
程序为了保证多线程处理,可以采取以下两种方法:第一种办法是让缓冲数组成为静态数组,既可以直接显式声明buf 为静态;第二种办法是动态分配缓冲区(malloc)。
5.4 使用errno检测错误
很多库函数,特别是那些与操作系统有关的,当执行失败时会通过一个名称为errno 的外部变量,通知程序该函数调用失败。
在使用errno进行判断之前应该先对库函数的返回值进行判断(确认出错),再对errno进行判断。
因为在库函数调用没有失败的情况下,并没有强制要求库函数一定要设置errno为0,这样errno的值就可能是前一个执行失败的库函数设置的值。
5.5 库函数signal
实际上所有的C语言实现中都包括有signal 库函数,作为捕获异步事件的一种方式。要使用该库函数,需要在源文件中加上