C语言之错误处理
在C语言中,错误处理是一种重要的编程技术,用于处理程序运行过程中可能出现的错误情况。C语言提供了几种处理错误的机制,包括返回错误码、使用全局变量、异常处理等。
1、返回错误码: 在函数执行过程中,如果发生错误,可以通过返回一个特定的错误码来表示错误的类型。通常情况下,函数的返回值为0表示成功,非零值表示错误。这种方式需要在函数声明时明确指定返回类型为错误码,并在函数体内根据错误情况返回相应的错误码。
例如:
int divide(int a, int b, int* result) {if (b == 0) {return -1; // 表示除数为0的错误}*result = a / b;return 0; // 表示成功
}
调用方可以通过检查函数的返回值来确定函数是否执行成功,并根据返回的错误码进行相应的处理。
2、使用全局变量: 另一种处理错误的方式是使用全局变量来记录错误信息。在函数执行过程中,如果发生错误,将错误信息保存到全局变量中,调用方可以通过读取该全局变量来获取错误信息。
例如:
#include <stdio.h>int error_code = 0;
char error_msg[100];void divide(int a, int b, int* result) {if (b == 0) {error_code = -1;sprintf(error_msg, "除数为0");return;}*result = a / b;
}
调用方可以在调用函数后检查全局变量的值,以确定是否发生了错误,并获取相应的错误信息。
3、异常处理: C语言本身并没有内置的异常处理机制,但可以使用一些库或自定义的方法来实现类似的功能。例如,可以使用setjmp和longjmp函数来进行异常处理。setjmp函数设置一个跳转点,longjmp函数用于从跳转点直接跳转到指定位置,从而实现异常的捕获和处理。
例如:
#include <stdio.h>
#include <setjmp.h>jmp_buf jump_buffer;void divide(int a, int b, int* result) {if (b == 0) {longjmp(jump_buffer, -1);}*result = a / b;
}int main() {int result;if (setjmp(jump_buffer) != 0) {printf("除数为0\n");return -1;}divide(10, 0, &result);printf("结果:%d\n", result);return 0;
}
在上述示例中,如果除数为0,则调用longjmp函数跳转到setjmp函数处,并返回指定的错误码。
4、断言: 断言是一种在程序中检查某个条件是否成立的方法。如果条件不成立,则会触发一个断言错误,并终止程序的执行。断言通常用于调试过程中,帮助开发者快速定位问题所在。
例如:
#include <stdio.h>
#include <assert.h>void divide(int a, int b, int* result) {assert(b != 0); // 断言除数不为0*result = a / b;
}int main() {int result;divide(10, 0, &result);printf("结果:%d\n", result);return 0;
}
在上述示例中,如果除数为0,则会触发一个断言错误,并终止程序的执行。
5、日志记录: 日志记录是一种记录程序运行过程中信息的方法,包括错误信息、警告信息、调试信息等。通过记录日志,可以帮助开发者追踪程序的执行过程,定位问题所在。在C语言中,可以使用一些日志库来实现日志记录功能,如log4c、syslog等。
例如:
#include <stdio.h>
#include <stdlib.h>
#include <syslog.h>void divide(int a, int b, int* result) {if (b == 0) {syslog(LOG_ERR, "除数为0"); // 记录错误日志exit(1); // 终止程序的执行}*result = a / b;
}int main() {int result;openlog("myapp", LOG_PID, LOG_USER); // 打开日志divide(10, 0, &result);printf("结果:%d\n", result);closelog(); // 关闭日志return 0;
}
6、处理错误信息:在C语言中,errno、perror()和strerror()是用于处理错误信息的重要函数。
- errno: errno是一个全局变量,用于表示最近发生的错误代码。在C标准库中的很多函数在发生错误时会将相应的错误代码存储在errno中。通过检查errno的值,可以确定函数是否成功执行,以及具体的错误类型。
- perror(): perror()函数用于打印与errno相关的错误消息。它接受一个字符串作为参数,并在该字符串后面输出当前的errno值对应的错误消息。通常,这个字符串是用来描述出错的上下文信息,以便更好地理解错误的原因。
- strerror(): strerror()函数返回一个指针,指向当前errno值对应的错误消息的字符串表示形式。它接受一个整数参数,该参数通常是errno的值。通过调用strerror(errno),可以获取到与errno相关的错误消息,然后可以根据需要进行处理或输出。
下面是一个示例代码,演示了如何使用errno、perror()和strerror()来处理错误信息:
#include <stdio.h>
#include <errno.h>
#include <string.h>int main() {FILE* file = fopen("nonexistent.txt", "r");if (file == NULL) {int errnum = errno;fprintf(stderr, "错误号: %d\n", errno);perror("通过 perror 输出错误");fprintf(stderr, "打开文件错误: %s\n", strerror(errnum));} else {// 执行文件操作fclose(file);}return 0;
}
在这个示例中,我们尝试以只读方式打开一个不存在的文件"nonexistent.txt"。由于文件不存在,fopen()函数将返回NULL,并且errno被设置为对应的错误代码。
接下来,我们将errno的值存储在errnum变量中,然后使用fprintf()函数将errno的值输出到标准错误流stderr。接着,使用perror()函数输出与errno相关的错误消息,它会在我们提供的字符串后面输出当前errno值的文本表示形式。
最后,我们使用strerror()函数将errnum的值转换为相应的错误消息字符串,并通过fprintf()函数输出到标准错误流stderr。
当我们运行这段代码时,输出将类似于以下内容:
错误号: 2
通过 perror 输出错误: No such file or directory
打开文件错误: No such file or directory
这个示例展示了如何利用errno、perror()和strerror()函数来获取和输出与错误相关的信息,有助于更好地理解和处理错误情况,,使得调试和错误修复变得更加方便和有效。
相关文章:
C语言之错误处理
在C语言中,错误处理是一种重要的编程技术,用于处理程序运行过程中可能出现的错误情况。C语言提供了几种处理错误的机制,包括返回错误码、使用全局变量、异常处理等。 1、返回错误码: 在函数执行过程中,如果发生错误&a…...
IO流框架,缓冲流
一.缓冲流有什么优点 Java中的缓冲流(Buffered Stream)具有以下优势: 提高效率:缓冲流通过在内存中缓存一部分数据,减少了直接从内存到磁盘或从磁盘到内存的频繁IO操作,从而提高了读写效率。缓冲区大小调整…...
数字音频工作站软件 Ableton Live 11 mac中文软件特点与功能
Ableton Live 11 mac是一款数字音频工作站软件,用于音乐制作、录音、混音和现场演出。它由Ableton公司开发,是一款极其流行的音乐制作软件之一。 Ableton Live 11 mac软件特点和功能 Comping功能:Live 11增加了Comping功能,允许用…...
【PyQt】调整子控件的层级以调整绘制的先后顺序
简述 qt中貌似没有直接设置z序的函数,但对应的有其他调整z序的方法: QWidget.raise_():置顶 QWidget.lower():置底 QWidget.stackUnder(wid):置于指定控件之下 其中关键函数是QWidget.stackUnder(wid),利…...
js中数组的相关方法
引言: 数组(Array)是有序的元素序列。 [1]若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量 方法: push()…...
深入浅出排序算法之直接插入排序(拓展:折半插入排序)
目录 1. 图示解析 2. 原理解析 3. 代码实现 4. 性能分析 5. 折半插入排序(拓展) 直接插入排序和选择排序的第一趟就是第一个关键字 ! 1. 图示解析 2. 原理解析 整个区间被分为:① 有序区间;② 无序区间 每次选…...
皮卡丘RCE靶场通关攻略
皮卡丘RCE靶场通关攻略 文章目录 皮卡丘RCE靶场通关攻略RCE(remote command/code execute)概述远程系统命令执行启动环境漏洞练习第一关exec "ping"第二关 exec "eval" RCE(remote command/code execute)概述 RCE漏洞,可以让攻击者直接向后台服…...
Mysql binlog日志功能使用,简单易懂
一、简单了解binlog MySQL的二进制日志binlog可以说是MySQL最重要的日志,它记录了所有的DDL和DML语句(除了数据查询语句select)。因此binlog日志文件我们用cat等查看文件的命令是打不开的,但是mysql提供了专门看binlog文件的命令…...
计算机视觉-光源的目的和作用
光源的目的 机器视觉系统的核心是图像采集和图像处理,而光源则是影响图像水平的重要因素,通过适当的光源照明,使图像中的目标信息与背景信息得到更好的分离,可大大降低图像识别难度,提高系统的精度和可靠性。 对于机器…...
源码角度分析Java 循环中删除数据为什么会报异常
一、源码角度分析Java 循环中删除数据为什么会报异常 相信大家在之前或多或少都知道 Java 中在增强 for中删除数据会抛出:java.util.ConcurrentModificationException 异常,例如:如下所示程序: public class RmTest {public sta…...
leetCode 229. 多数元素 II + 摩尔投票法 + 进阶 + 优化空间
229. 多数元素 II - 力扣(LeetCode) 给定一个大小为 n 的整数数组,找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 进阶:尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。 (1)哈希表 class …...
5 个编写高效 Makefile 文件的最佳实践
在软件开发过程中,Makefile是一个非常重要的工具,它可以帮助我们自动化构建、编译、测试和部署。然而,编写高效的Makefile文件并不是一件容易的事情。在本文中,我们将讨论如何编写高效的Makefile文件,以提高我们的开发…...
20231028刷题记录
P3381 【模板】最小费用最大流 Portal. sol. 注意 SPFA 找最小费用增广路时不要到终点就返回,因为到终点的路径可能有多条不能确定哪条是费用最小的。 P2740 [USACO4.2] 草地排水Drainage Ditches Portal. 最大流模板。 注意区分 N , M N,M N,M。 CF609D G…...
39 深度学习(三):tensorflow.data模块的使用(基础,可跳)
文章目录 data模块的使用基础api的介绍csv文件tfrecord data模块的使用 在训练的过程中,当数据量一大的时候,我们纯读取一个文件,然后每次训练都调用相同的文件,然后进行处理是很不科学的,或者说,当我们需…...
css四种导入方式
1 行内样式 <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>Title</title> </head> <body> <h1 style"color: blue">我是标题</h1> </body> </htm…...
Linux学习第24天:Linux 阻塞和非阻塞 IO 实验(一): 挂起
Linux版本号4.1.15 芯片I.MX6ULL 大叔学Linux 品人间百味 思文短情长 在正式开始今天的笔记之前谈一下工作中遇见的一个问题。 本篇笔记主要学习Linux 阻塞和非阻塞 IO 实验,主要包括阻塞和非阻塞简介、等待队列、轮询、…...
037-第三代软件开发-系统音量设置
第三代软件开发-系统音量设置 文章目录 第三代软件开发-系统音量设置项目介绍系统音量设置QML 实现C 实现 总结一下 关键字: Qt、 Qml、 volume、 声音、 GPT 项目介绍 欢迎来到我们的 QML & C 项目!这个项目结合了 QML(Qt Meta-Obj…...
Python 自动化详解(pyautogui)
文章目录 1 概述1.1 第三方库:pyautogui1.2 坐标说明 2 操作对象2.1 鼠标2.1.1 定位2.1.2 移动2.1.3 拖动2.1.4 滚动2.1.5 点击 2.2 键盘2.2.1 输入2.2.2 按键2.2.3 快捷键 2.3 屏幕2.3.1 截图2.3.2 分辨率 2.4 信息提示2.4.1 提示框2.4.2 选择框2.4.3 密码输入2.4.…...
【Linux】第四站:Linux基本指令(三)
文章目录 一、时间相关的指令1.指令简介2.使用 二、cal指令三、find指令 -name1.介绍2.使用 四、grep指令1.介绍2.使用 五、zip/unzip指令1.介绍2.zip的安装3.使用 六、tar指令:打包解包,不打开它、直接看内容1.介绍2.使用 七、bc指令八、uname -r指令1.…...
SpringBoot内置工具类之断言Assert的使用与部分解析
先例举一个service的demo中用来验证参数对象的封装方法,使用了Assert工具类后是不是比普通的 if(xxx) { throw new RuntimeException(msg) } 看上去要简洁多了? 断言Assert工具类简介 断言是一个判断逻辑,用来检查不该发生的情况ÿ…...
【JavaEE】-- HTTP
1. HTTP是什么? HTTP(全称为"超文本传输协议")是一种应用非常广泛的应用层协议,HTTP是基于TCP协议的一种应用层协议。 应用层协议:是计算机网络协议栈中最高层的协议,它定义了运行在不同主机上…...
UE5 学习系列(三)创建和移动物体
这篇博客是该系列的第三篇,是在之前两篇博客的基础上展开,主要介绍如何在操作界面中创建和拖动物体,这篇博客跟随的视频链接如下: B 站视频:s03-创建和移动物体 如果你不打算开之前的博客并且对UE5 比较熟的话按照以…...
ServerTrust 并非唯一
NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...
04-初识css
一、css样式引入 1.1.内部样式 <div style"width: 100px;"></div>1.2.外部样式 1.2.1.外部样式1 <style>.aa {width: 100px;} </style> <div class"aa"></div>1.2.2.外部样式2 <!-- rel内表面引入的是style样…...
2025季度云服务器排行榜
在全球云服务器市场,各厂商的排名和地位并非一成不变,而是由其独特的优势、战略布局和市场适应性共同决定的。以下是根据2025年市场趋势,对主要云服务器厂商在排行榜中占据重要位置的原因和优势进行深度分析: 一、全球“三巨头”…...
MFC 抛体运动模拟:常见问题解决与界面美化
在 MFC 中开发抛体运动模拟程序时,我们常遇到 轨迹残留、无效刷新、视觉单调、物理逻辑瑕疵 等问题。本文将针对这些痛点,详细解析原因并提供解决方案,同时兼顾界面美化,让模拟效果更专业、更高效。 问题一:历史轨迹与小球残影残留 现象 小球运动后,历史位置的 “残影”…...
C语言中提供的第三方库之哈希表实现
一. 简介 前面一篇文章简单学习了C语言中第三方库(uthash库)提供对哈希表的操作,文章如下: C语言中提供的第三方库uthash常用接口-CSDN博客 本文简单学习一下第三方库 uthash库对哈希表的操作。 二. uthash库哈希表操作示例 u…...
Spring Security 认证流程——补充
一、认证流程概述 Spring Security 的认证流程基于 过滤器链(Filter Chain),核心组件包括 UsernamePasswordAuthenticationFilter、AuthenticationManager、UserDetailsService 等。整个流程可分为以下步骤: 用户提交登录请求拦…...
HybridVLA——让单一LLM同时具备扩散和自回归动作预测能力:训练时既扩散也回归,但推理时则扩散
前言 如上一篇文章《dexcap升级版之DexWild》中的前言部分所说,在叠衣服的过程中,我会带着团队对比各种模型、方法、策略,毕竟针对各个场景始终寻找更优的解决方案,是我个人和我司「七月在线」的职责之一 且个人认为,…...
自然语言处理——文本分类
文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...
