C陷阱与缺陷--读书笔记5 库函数
第五章
一、知识点
1、对于一个例子:
#include <stdio.h>
main(){
char c;
while((c = getchar()) !=EOF)
putchar(c);
}
getchar函数在一般情况下返回的是标准输入文件中的下一个字符,当没有输入时返回EOF。这依程序乍一看似乎是把标准输入复制到标准输,实则不然。
原因在于程序中的变量c被声明为char型,而不是int类型。这意味着c无法容下所有可能的字符,特别是,可能无法容下EOF。(P92)
2、更新顺序文件:(P93)
![]()
3、C语言实现通常都允许程序员进行实际的写操作之前控制产生的输出数量。这种控制能力一般通过库函数setbuf实现的。如果buf是一个大小适当的字符数组,那么
setbuf(stdout, buf);
语句将通知输入/输出库,所有写入到stdout 的输出都应该使用buf作为输出缓冲区,直到buf缓冲区被填满或者程序员直接调用fflush(对于由写操作打开的文件,调用fflush将导致输出缓冲区的内容被实际写入该文件),buf缓冲区的内容才实际写入到stdout中。缓冲区的大小由系统头文件<stdio.h>中的BUFSIZ定义。(P95)
4、把标准输入的内容复制到标准输出中:(P96)
#include <stdio.h>
main()
{
int c;
char buf[BUFSIZ];
setbuf(stdout, buf);
while((c = getchar()) != EOF)
putchar(c);
}
实际上,上述程序是错误的,因为buf缓冲区最后一次被清空实在main函数结束之后,作为程序交回控制给操作系统之前C运行时库所必须进行的清理工作的一部分。但是,在此之前buf字符数组已经被释放!解决办法一:让缓冲数组称为静态数组;二:动态分配缓冲区,在程序中并不主动释放分配的缓冲区。
5、使用errno检测错误,对于代码:(P96)
/* 调用库函数 */
if (errno)
/* 处理错误 */
这段代码是错误的,原因在于,在库函数调用没有失败的情况下,并没有强制要求库函数一定要设置为0,这样errno的值就可能是前一个执行失败的库函数设置的值。下面的代码作了更正,似乎能够工作,但还是错的:
errno = 0;
/ * 调用库函数 */
if (errno)
/* 处理错误 */
库函数在调用成功时,既没有强制要求对errno清零,但同时也没有禁止设置errno。既然库函数已经调用成功了,为什么还有可能设置errno呢?、
6、函数调用需要花费较长的程序执行时间,因此getchar经常被实现为宏。这个宏在stdio.h头文件中定义,因此如果一个程序没有包含stdio.h头文件,编译器对getchar的定义就一无所知。(P143)
二、问题
1、getchar() ?
2、更新顺序文件?
3、静态数组何时释放?
4、当一个程序异常终止时,程序输出的最后几行常常会丢失,原因是什么?我们能够采取怎么样的措施来解决这个问题?
答: