重回C语言之老兵重装上阵(十五)C语言错误处理
C语言错误处理
在C语言中,错误处理是非常重要的一部分。C语言没有像高级语言(例如Python、Java)那样内建的异常处理机制(如try-catch
),但它提供了几种方法来捕捉和处理错误。正确的错误处理可以提高程序的稳定性,帮助开发人员及时发现和解决问题。
1. 返回值检查
C语言的错误处理通常通过函数的返回值来传递错误信息。很多标准库函数会通过返回值表示操作是否成功。如果返回值为特殊值,通常表示发生了错误。
示例:fopen
错误处理
#include <stdio.h>int main() {FILE *file = fopen("nonexistent_file.txt", "r");if (file == NULL) {// 打开文件失败printf("Error: Unable to open file.\n");return 1; // 返回错误码}// 成功打开文件后处理文件内容fclose(file);return 0; // 正常结束
}
分析:
fopen
打开文件失败时返回NULL
,程序可以通过检查返回值来确认是否发生错误。- 如果失败,程序打印错误信息并返回一个非零的错误码。
2. 使用 errno
和 perror
在很多C语言库函数中,错误会通过设置全局变量 errno
来传递。errno
保存了最近一次系统调用或库函数发生错误时的错误码。
errno
定义在<errno.h>
中。perror
是一个标准库函数,用于打印errno
对应的错误信息。
示例:fopen
错误处理使用 errno
和 perror
#include <stdio.h>
#include <errno.h>
#include <string.h>int main() {FILE *file = fopen("nonexistent_file.txt", "r");if (file == NULL) {// 打印详细的错误信息printf("Error opening file: %s\n", strerror(errno));return 1;}fclose(file);return 0;
}
分析:
errno
被设置为系统调用失败的错误代码,strerror(errno)
用于转换该错误码为易于理解的错误信息。perror
也是一个用于输出错误信息的标准函数,它自动结合了errno
的值并输出错误消息。
3. assert
宏(调试时使用)
C语言中提供了一个调试工具 assert
,用于检查程序中不应该发生的条件。如果条件为假,assert
会打印错误信息并中止程序。
示例:使用 assert
来检查不应发生的条件
#include <stdio.h>
#include <assert.h>int main() {int x = -1;// 检查x是否为正数assert(x >= 0);printf("This will not be printed if x is negative.\n");return 0;
}
分析:
assert(x >= 0)
会检查x
是否大于或等于0。如果条件不成立(即x
为负数),程序将终止,并输出失败的条件表达式。assert
仅在调试模式下有效,在发布版本中通常会被禁用。
4. 自定义错误处理函数
在一些复杂的程序中,可以编写自定义的错误处理函数来统一管理错误。例如,可以创建一个 error_handler()
函数,在发生错误时打印详细的错误信息并决定如何恢复或退出程序。
示例:自定义错误处理函数
#include <stdio.h>
#include <stdlib.h>void error_handler(const char *msg) {perror(msg); // 打印系统错误信息exit(EXIT_FAILURE); // 退出程序
}int main() {FILE *file = fopen("nonexistent_file.txt", "r");if (file == NULL) {error_handler("Failed to open file");}fclose(file);return 0;
}
分析:
error_handler
函数负责处理错误,打印系统错误信息并终止程序。exit(EXIT_FAILURE)
用于退出程序并返回错误状态码。
5. 错误恢复和退出策略
当错误发生时,有时我们可能希望恢复程序的执行而不是直接退出。为了实现这一目标,可以返回错误代码,或者通过其他机制(如设置标志位)来通知程序如何恢复。
示例:通过返回错误代码来处理错误
#include <stdio.h>int divide(int a, int b) {if (b == 0) {printf("Error: Division by zero.\n");return -1; // 返回错误代码}return a / b;
}int main() {int result = divide(10, 0);if (result == -1) {// 错误处理,恢复程序或退出printf("Program could not continue.\n");return 1; // 错误退出}printf("Result: %d\n", result);return 0; // 成功退出
}
分析:
divide()
函数在除数为0时返回错误代码-1
。- 主程序通过检查返回值来决定如何处理错误。如果发生错误,可以选择退出或恢复操作。
6. 总结
C语言的错误处理主要依赖于以下方法:
- 返回值检查:通过检查函数的返回值来确认操作是否成功。
errno
和perror
:通过errno
获取错误码并使用perror
打印系统错误信息。assert
:用于调试时检查不应发生的条件。- 自定义错误处理函数:编写统一的错误处理函数,提高程序的可维护性。
- 错误恢复策略:根据返回的错误代码或标志位来决定如何恢复或退出程序。
相关文章:
重回C语言之老兵重装上阵(十五)C语言错误处理
C语言错误处理 在C语言中,错误处理是非常重要的一部分。C语言没有像高级语言(例如Python、Java)那样内建的异常处理机制(如try-catch),但它提供了几种方法来捕捉和处理错误。正确的错误处理可以提高程序的稳…...

基于微信的课堂助手小程序设计与实现(LW+源码+讲解)
专注于大学生项目实战开发,讲解,毕业答疑辅导,欢迎高校老师/同行前辈交流合作✌。 技术范围:SpringBoot、Vue、SSM、HLMT、小程序、Jsp、PHP、Nodejs、Python、爬虫、数据可视化、安卓app、大数据、物联网、机器学习等设计与开发。 主要内容:…...
Effective C++ 规则50:了解 new 和 delete 的合理替换时机
1、背景 在 C 中,new 和 delete 是动态分配内存的核心操作符。然而,直接使用它们有时会增加程序的复杂性,甚至导致内存泄漏和其他问题。因此,了解何时替换 new 和 delete 并选择更适合的内存管理策略,是编写高效、健壮…...

Alfresco Content Services dockerCompose自动化部署详尽操作
Alfresco Content Services docker社区部署文档 Alfresco Content Services简介 Alfresco Content Services(简称ACS)是一款功能完备的企业内容管理(ECM)解决方案,主要面向那些对企业级内容管理有高要求的组织。具体…...
学习第七十六行
提高github下载速度方法 1.github转码云 2.https://github.com.cnpmjs.org com后面加东西 对于面试笔试,最好方法刷力扣,1000题包进大厂的...

YOLOv11改进,YOLOv11检测头融合DynamicHead,并添加小目标检测层(四头检测),适合目标检测、分割等任务
摘要 作者提出一种新的检测头,称为“动态头”,旨在将尺度感知、空间感知和任务感知统一在一起。如果我们将骨干网络的输出(即检测头的输入)视为一个三维张量,其维度为级别 空间 通道,这样的统一检测头可以看作是一个注意力学习问题,直观的解决方案是对该张量进行全自…...

一个基于Python+Appium的手机自动化项目~~
本项目通过PythonAppium实现了抖音手机店铺的自动化询价,可以直接输出excel,并带有详细的LOG输出。 1.excel输出效果: 2. LOG效果: 具体文件内容见GitCode: 项目首页 - douyingoods:一个基于Pythonappium的手机自动化项目,实现了…...

【后端开发】字节跳动青训营之性能分析工具pprof
性能分析工具pprof 一、测试程序介绍二、pprof工具安装与使用2.1 pprof工具安装2.2 pprof工具使用 资料链接: 项目代码链接实验指南pprof使用指南 一、测试程序介绍 package mainimport ("log""net/http"_ "net/http/pprof" // 自…...

Linux:线程池和单例模式
一、普通线程池 1.1 线程池概念 线程池:一种线程使用模式。线程过多会带来调度开销,进而影响缓存局部性和整体性能。而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建与销毁线程的代价&…...
使用iis服务器模拟本地资源服务器unityaddressables热更新出错记录
editor中设置了using exculexing 模拟远程加载addressable可以实现资源热更新,build后的软件却没有成功。 iis服务器中mime中需要设置bundle的文件扩展名,时editor成功,build后失败 原因没有设置hash的扩展名,设置后editor和buil…...
TikTok广告投放优化策略:提升ROI的核心技巧
在短许多品牌和商家纷纷投入广告营销,争夺这片潜力巨大的市场。然而,在激烈的竞争环境中,如何精准有效地投放广告,优化广告效果,实现更高的投资回报率(ROI)成为了广告主关注的核心。 一. 精准受…...
Hash表
哈希表存储结构(开放寻址法,拉链法)字符串哈希方式(添加、查找h(x)) 常见从0~10^9映射到0~10^5就要对10^5取mod(取模一般要质数最好)但是可能会有冲突 1.拉链法:O(1),每…...
题解:P10972 I-Country
题目传送门 思路 因为占据的连通块的左端点先递减、后递增,右端点先递增、后递减,所以设 f i , j , l , r , x ( 0 / 1 ) , y ( 0 / 1 ) f_{i,j,l,r,x(0/1),y(0/1)} fi,j,l,r,x(0/1),y(0/1) 为前 i i i 行中,选择 j j j 个方格&#x…...

linux常用加固方式
目录 一.系统加固 二.ssh加固 三.换个隐蔽的端口 四.防火墙配置 五.用户权限管理 六.暴力破解防护 七.病毒防护 八.磁盘加密 九.双因素认证2FA 十.日志监控 十一.精简服务 一.系统加固 第一步:打好系统补丁 sudo apt update && sudo apt upgra…...
笔灵ai写作技术浅析(二):自然语言处理
一、词法分析(Lexical Analysis) 1.1 概述 词法分析是NLP的第一步,主要任务是将连续的文本分割成有意义的单元(词或词组),并对这些单元进行标注,如词性标注(POS tagging)。词法分析的质量直接影响后续的句法分析和语义理解。 1.2 技术细节 1.分词(Tokenization)…...
PyCharm介绍
PyCharm的官网是https://www.jetbrains.com/pycharm/。 以下是在PyCharm官网下载和安装软件的步骤: 下载步骤 打开浏览器,访问PyCharm的官网https://www.jetbrains.com/pycharm/。在官网首页,点击“Download”按钮进入下载页面。选择适合自…...

深度解析:基于Vue 3与Element Plus的学校管理系统技术实现
一、项目架构分析 1.1 技术栈全景 核心框架:Vue 3 TypeScript UI组件库:Element Plus(含图标动态注册) 状态管理:Pinia(用户状态持久化) 路由方案:Vue Router(动态路…...

Python从0到100(八十五):神经网络-使用迁移学习完成猫狗分类
前言: 零基础学Python:Python从0到100最新最全教程。 想做这件事情很久了,这次我更新了自己所写过的所有博客,汇集成了Python从0到100,共一百节课,帮助大家一个月时间里从零基础到学习Python基础语法、Python爬虫、Web开发、 计算机视觉、机器学习、神经网络以及人工智能…...
苍穹外卖 项目记录 day09 历史订单
文章目录 查询历史订单查询订单详情取消订单再来一单 查询历史订单 分页查询历史订单可以根据订单状态查询展示订单数据时,需要展示的数据包括:下单时间、订单状态、订单金额、订单明细(商品名称、图片) #OrderController/*** 历…...

记录 | 基于Docker Desktop的MaxKB安装
目录 前言一、MaxKBStep 1Step2 二、运行MaxKB更新时间 前言 参考文章:如何利用智谱全模态免费模型,生成大家都喜欢的图、文、视并茂的文章! MaxKB的Github下载地址 参考视频:【2025最新MaxKB教程】10分钟学会一键部署本地私人专属…...

网络编程(Modbus进阶)
思维导图 Modbus RTU(先学一点理论) 概念 Modbus RTU 是工业自动化领域 最广泛应用的串行通信协议,由 Modicon 公司(现施耐德电气)于 1979 年推出。它以 高效率、强健性、易实现的特点成为工业控制系统的通信标准。 包…...

接口测试中缓存处理策略
在接口测试中,缓存处理策略是一个关键环节,直接影响测试结果的准确性和可靠性。合理的缓存处理策略能够确保测试环境的一致性,避免因缓存数据导致的测试偏差。以下是接口测试中常见的缓存处理策略及其详细说明: 一、缓存处理的核…...
ubuntu搭建nfs服务centos挂载访问
在Ubuntu上设置NFS服务器 在Ubuntu上,你可以使用apt包管理器来安装NFS服务器。打开终端并运行: sudo apt update sudo apt install nfs-kernel-server创建共享目录 创建一个目录用于共享,例如/shared: sudo mkdir /shared sud…...

通过Wrangler CLI在worker中创建数据库和表
官方使用文档:Getting started Cloudflare D1 docs 创建数据库 在命令行中执行完成之后,会在本地和远程创建数据库: npx wranglerlatest d1 create prod-d1-tutorial 在cf中就可以看到数据库: 现在,您的Cloudfla…...
服务器--宝塔命令
一、宝塔面板安装命令 ⚠️ 必须使用 root 用户 或 sudo 权限执行! sudo su - 1. CentOS 系统: yum install -y wget && wget -O install.sh http://download.bt.cn/install/install_6.0.sh && sh install.sh2. Ubuntu / Debian 系统…...
C#中的CLR属性、依赖属性与附加属性
CLR属性的主要特征 封装性: 隐藏字段的实现细节 提供对字段的受控访问 访问控制: 可单独设置get/set访问器的可见性 可创建只读或只写属性 计算属性: 可以在getter中执行计算逻辑 不需要直接对应一个字段 验证逻辑: 可以…...

pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...

WPF八大法则:告别模态窗口卡顿
⚙️ 核心问题:阻塞式模态窗口的缺陷 原始代码中ShowDialog()会阻塞UI线程,导致后续逻辑无法执行: var result modalWindow.ShowDialog(); // 线程阻塞 ProcessResult(result); // 必须等待窗口关闭根本问题:…...
stm32进入Infinite_Loop原因(因为有系统中断函数未自定义实现)
这是系统中断服务程序的默认处理汇编函数,如果我们没有定义实现某个中断函数,那么当stm32产生了该中断时,就会默认跑这里来了,所以我们打开了什么中断,一定要记得实现对应的系统中断函数,否则会进来一直循环…...
Linux中INADDR_ANY详解
在Linux网络编程中,INADDR_ANY 是一个特殊的IPv4地址常量(定义在 <netinet/in.h> 头文件中),用于表示绑定到所有可用网络接口的地址。它是服务器程序中的常见用法,允许套接字监听所有本地IP地址上的连接请求。 关…...