C/C++笔记(01):容易出错的几个库函数

大多数库函数的使用都不会有什么问题,它们的意义和用法明白而直接,基本上都能正确的使用它们,但也有一些例外情况,如一些常用到的库函数表现出来的行为方式往往有悖于使用者的本意(尤其是我们初学者),今天我们就来讨论一些常用到的库函数,以及使用过程中可能出错之处。

1. 返回整数的getchar 函数

我们先来看一个简单的例子:

# include <stdio.h>
int main(void)
{
    char c;
while((c = getchar())!= EOF)
    putchar(c);
return 0;
}
复制代码

getchar 函数在一般情况下返回的是标准输入文件中的下一个字符,当没有输入时返回EOF,这个程序看似是把标准输入复制到标准输出,实则不是,原因在于程序中的变量c 被声明为char 类型,而不是int类型,这意味着无法容下所有的字符,特别是无法容下EOF。

因此,最终结果有两种可能: 一种是,某些合法的输入字符在被截断后是的c的取值与EOF 相同。
另一种是,c 根本不可能取到EOF这个值。
总结:对于第一种情况,程序在文件复制的中途终止;对于后一种情况,程序将陷入一个死循环。实际上,还存在了第三种情况,程序表面上似乎能够正常工作,那是因为巧合。尽管函数getchar的返回记过在赋给char类型的变量c时会发生截断操作。将返回值的地位数据赋给c,但与EOF的比较不是c,而是getchar的返回值,编译器如果采用这种做法,上面的程序就可以正常运行了。

2. 跟新顺序文件

许多系统中的标准输入/输入库都允许程序打开一个文件,同时进行写入和读取的操作。
FILE * fp; fp = fopen(file,”r+”); 上面的例子代码打开了文件名由变量file指定的文件,对于存取权限的设定表明程序希望对这个文件进行输入和输出操作。
编程者也许认为,程序一旦执行上述操作完毕,就可以自由的交错进行读出和写入的操作.但事实上并不是我们想象的那样,我们在进行了读操作或者写操作之后,都会改变文件指针的位置。因此,先要同时进行输入和输出操作,必须使用 fseek 函数改变文件指针的位置。

3. 使用errno 检测错误

很多库函数,特别是与操作系统相关的,当执行失败时会通过一个名称为 errno 的外部变量,通知程序该函数调用失败。请看下面的额例子:

 /*调用库函数*/
if (errno)
 /*处理错误*/
复制代码

这是一个简单的错误处理程序,看起来没问题,然而却是错误的。出错原因在于,在库函数调用没有失败的情况下,并没有强制要求库函数一定设置errno为0,这样errno 的值就可能是前一个执行失败的库函数设置的值。我们对代码做了一下调整,看似正确,但可能还是错误的:

Errno = 0;
/*调用库函数*/
if(errno)
/*出错处理*/
复制代码

原因在于,库函数在调用成功后,即没有强制要求对errno清零,同时也没有禁止设置errno。因为在调用一个函数的时候,可能会在内部调用另一个函数,此时可能设置errno。
所以,在调用库函数时,我们应该首先检测作为错误指示的返回值,确定程序已经执行失败。然后,在检查errno,来搞清楚出错原因:

/* 调用库函数 */
if(返回的错误值)
    检查errno
复制代码

4. 库函数signal

实际上,所有的C语言实现中都包括有signal库函数,作为捕获异步事件的一种方式。要使用该库函数,需要在源文件中加上 #include <signal.h> 以引入先关的声明,要处理一个特定的signal(信号),可以这样调用signal函数:

signal(signal type, handle function);
--signal type 代表要处理的信号.
--handle function 代表信号发生时,调用的事件处理函数.
复制代码

在许多c语言实现中,信号是真正意义上的”异步”。从理论上说,一个信号可能在C程序执行期间的任何时刻发生,信号甚至可能出现在某些复杂的库函数(如malloc)的执行过程中。因此,信号的处理函数不应该调用上述类型的库函数。
我们需要让signal处理函数尽可能的简单,并将它们组织在一起,这样,当需要适应一个系统时,我们可以很容易的进行修改。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值