c语言中没有定义输入输出语句,必须调用库函数来完成最基本的的输入/输出操作。
一个容易出错的例子:
main
{
char c;
while((c=getchar())!=EOF)
putchar(c);
}
程序可能不会按照预想的那样把标准输入复制到标准输出,而可能是中途终止或进入一个死循环。
原因在于c是char型,而不是int型,这意味着c不能容纳所有可能的字符,特别是,可能无法容纳EOF。
当使用库函数对文件进行操作时,如果要同时进行输入和输出操作,那么其中必须插入fseek函数的调用。
fread
fseek
fwrite
fseek
fwrite
使用errno检测错误
if(errno)
/*处理错误*/
上面这种处理方式是错误的,因为在库函数调用没有失败的时候并没有强制errno为0,也就是存在函数正确调用后将errno设置为非0的情况,解决方案是:在调用库函数时,首先检测作为错误指示的返回值,确定程序执行失败,然后根据errno来定位错误原因。
if(返回错误的值)
检查 errno;
signal库函数可以在可以捕捉信号对应的异步事件,并使用指定的函数作出处理,可是这个事件处理函数的使用是很危险的,比如你在内存分配的过程中响应了异步信号,然后调用相应的处理函数,如果这个处理函数中也用到了内存分配函数,那么可能导致内存分配用到的数据结构完全崩溃。所以signal处理函数所能做的最安全的事情就是设置一个标志然后返回,期待以后的主程序能够检查到这个标志,发现信号发生。
练习
5-1 当一个程序异常终止时,程序输出的最后几行会消失,为啥,咋解决。
原因是,程序异常终止时,可能没有清空缓冲区,导致一些输出还滞留在内存中而没有输出来。
这种错误会导致程序员对程序发生错误的时刻估计过早(其实一些语句没有错误,只是正确的输出还在缓冲里)。
解决的方法就是,在调试时强制输出不做任何缓冲,在main函数的第一句加上这个语句:
setbuf(stdout,(char*)0)
5-2对于上面那个把输入复制到输出的程序,如果不include stdio.h,而是直接的人为定义EOF=-1,将导致程序运行起来非常慢,为啥
因为在c中,为了节省时间,常常把getchar定义为宏,可是如果不包含库文件,编译器会假定getchar是一个返回值为整型的函数(编译器对它不认识的函数的一贯做法,经过连接器后getchar就被认识了,但是由于编译器的原因,它被认成是一个函数)宏调用就变成了普通的函数调用,运行自然会慢。
阅读(875) | 评论(0) | 转发(0) |