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处理函数尽可能的简单,并将它们组织在一起,这样,当需要适应一个系统时,我们可以很容易的进行修改。
C/C++笔记(01):容易出错的几个库函数相关推荐
- JavaWeb-综合案例(用户信息)-学习笔记01【列表查询】
Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb-综合案例(用户信息)-学习笔记01[列表查询] JavaWeb-综合案例(用户信息)-学习笔记02[登录功能] JavaWeb-综合案 ...
- [ESP32]学习笔记01
[ESP32]学习笔记01 学习笔记01 本开发工具使用ESP-IDF 工具链,非Arduino,关于ESP32-IDF工具链的安装方法可直接查看乐鑫官官方文档,CSDN上也有很多相关搭建开发环境的文 ...
- PHP 学习笔记 01
例子: 为什么要学PHP 主观原因: 前段时间在学校处理了毕业的一些事情,回到上海后开始了找工作的旅程.意向工作是WPF开发或者ASP.NET 作为后端的WEB开发. 陆陆续续一直在面试,其中有一家公 ...
- 状态机系列学习笔记01
状态机系列学习笔记01 有限状态机(FSM)概念 定义 总的来说,有限状态机系统,是指在不同阶段会呈现出不同的运行状态的系统,这些状态是有限的.不重叠的.这样的系统在某一时刻一定会处于其所有状态中的一 ...
- 《30天自制操作系统》笔记(01)——hello bitzhuwei’s OS!
<30天自制操作系统>笔记(01)--hello bitzhuwei's OS! 最初的OS代码 1 ; hello-os 2 ; TAB=4 3 4 ORG 0x7c00 ; 指明程序的 ...
- 独立式环境与宿主式环境————《标准C语言指南》读书笔记01
独立式环境与宿主式环境----<标准C语言指南>读书笔记01 在编写和转换一个C程序之前,需要考虑它的执行环境,因为这关系到源文件的内容(程序应当如何编写),也关系到转换后的程序能否正常执 ...
- MyBatis-学习笔记01【01.Mybatis课程介绍及环境搭建】
Java后端 学习路线 笔记汇总表[黑马程序员] MyBatis-学习笔记01[01.Mybatis课程介绍及环境搭建][day01] MyBatis-学习笔记02[02.Mybatis入门案例] M ...
- 微信公众号Java开发-笔记01【微信公众号介绍、开发环境搭建】
学习网址:哔哩哔哩网站 微信公众号开发-Java版 微信公众号Java开发-笔记01[微信公众号介绍.开发环境搭建] 微信公众号Java开发-笔记02[] 微信公众号Java开发-笔记03[] 微信公 ...
- JavaWeb黑马旅游网-学习笔记01【准备工作】
Java后端 学习路线 笔记汇总表[黑马程序员] JavaWeb黑马旅游网-学习笔记01[准备工作] JavaWeb黑马旅游网-学习笔记02[注册功能] JavaWeb黑马旅游网-学习笔记03[登陆和 ...
- Maven-学习笔记01【基础-Maven基本概念】
Java后端 学习路线 笔记汇总表[黑马程序员] 黑马程序员(腾讯微云)Maven基础讲义.pdf Maven-学习笔记01[基础-Maven基本概念] Maven-学习笔记02[基础-Maven的安 ...
最新文章
- 固件安全性—防止内存损坏和注入攻击
- C#内置函数 RunSql的使用
- hdu4685 最大匹配可能性
- 基于某网站的信息爬取与保存
- 富士康筹划在越南建造2.7亿美元新工厂,扩大生产线!
- 【Java】Java Long映射到浏览器或者JavaScript后损失精度
- 用FBI通缉犯照片集,考验亚马逊人脸识别,意外发现了隐情
- js typeof instanceof
- acs880变频器静态辨识_ACS880变频器PID控制参数设置 -
- 传统企业如何开启O2O营销模式?
- java swing 显示图片_Swing显示图片
- go 服务器压力测试,Go的单元测试与压力测试
- VS2013配置OpenCV3.4.0
- C语言之判断直角三角形
- switch函数不加break的效果
- 云服务器是干什么的 通俗易懂地解释一下
- 开源资产管理系统_OCR在资产管理系统的应用
- git repo仓库地址错误 /info/refs
- 地方门户运营 最全思路10条
- 【滤波跟踪】Singer-Kalman模型下的机动目标跟踪算法含Matlab源码
热门文章
- 【自动化__持续集成】___java___猜数字
- Spring中各个jar包的作用
- HDU3065 AC自动机
- 快到而立之年了,可是能撑得起而立吗?
- 用svn进行多人合作开发
- sql经典题目(1)
- 【CSS3】纯CSS代码实现模拟时钟,+js对时功能。
- 配置VS2008来Debug .Net框架源码
- [书目20080630]人一生要养成的50个习惯
- gbdt 算法比随机森林容易_数据挖掘面试准备(1)|常见算法(logistic回归,随机森林,GBDT和xgboost)...