当前位置: 首页 > news >正文

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语言中&#xff0c;错误处理是一种重要的编程技术&#xff0c;用于处理程序运行过程中可能出现的错误情况。C语言提供了几种处理错误的机制&#xff0c;包括返回错误码、使用全局变量、异常处理等。 1、返回错误码&#xff1a; 在函数执行过程中&#xff0c;如果发生错误&a…...

IO流框架,缓冲流

一.缓冲流有什么优点 Java中的缓冲流&#xff08;Buffered Stream&#xff09;具有以下优势&#xff1a; 提高效率&#xff1a;缓冲流通过在内存中缓存一部分数据&#xff0c;减少了直接从内存到磁盘或从磁盘到内存的频繁IO操作&#xff0c;从而提高了读写效率。缓冲区大小调整…...

数字音频工作站软件 Ableton Live 11 mac中文软件特点与功能

Ableton Live 11 mac是一款数字音频工作站软件&#xff0c;用于音乐制作、录音、混音和现场演出。它由Ableton公司开发&#xff0c;是一款极其流行的音乐制作软件之一。 Ableton Live 11 mac软件特点和功能 Comping功能&#xff1a;Live 11增加了Comping功能&#xff0c;允许用…...

【PyQt】调整子控件的层级以调整绘制的先后顺序

简述 qt中貌似没有直接设置z序的函数&#xff0c;但对应的有其他调整z序的方法&#xff1a; QWidget.raise_()&#xff1a;置顶 QWidget.lower()&#xff1a;置底 QWidget.stackUnder(wid)&#xff1a;置于指定控件之下 其中关键函数是QWidget.stackUnder(wid)&#xff0c;利…...

js中数组的相关方法

引言&#xff1a; 数组&#xff08;Array&#xff09;是有序的元素序列。 [1]若将有限个类型相同的变量的集合命名&#xff0c;那么这个名称为数组名。组成数组的各个变量称为数组的分量&#xff0c;也称为数组的元素&#xff0c;有时也称为下标变量 方法&#xff1a; push()…...

深入浅出排序算法之直接插入排序(拓展:折半插入排序)

目录 1. 图示解析 2. 原理解析 3. 代码实现 4. 性能分析 5. 折半插入排序&#xff08;拓展&#xff09; 直接插入排序和选择排序的第一趟就是第一个关键字 &#xff01; 1. 图示解析 2. 原理解析 整个区间被分为&#xff1a;① 有序区间&#xff1b;② 无序区间 每次选…...

皮卡丘RCE靶场通关攻略

皮卡丘RCE靶场通关攻略 文章目录 皮卡丘RCE靶场通关攻略RCE(remote command/code execute)概述远程系统命令执行启动环境漏洞练习第一关exec "ping"第二关 exec "eval" RCE(remote command/code execute)概述 RCE漏洞&#xff0c;可以让攻击者直接向后台服…...

Mysql binlog日志功能使用,简单易懂

一、简单了解binlog MySQL的二进制日志binlog可以说是MySQL最重要的日志&#xff0c;它记录了所有的DDL和DML语句&#xff08;除了数据查询语句select&#xff09;。因此binlog日志文件我们用cat等查看文件的命令是打不开的&#xff0c;但是mysql提供了专门看binlog文件的命令…...

计算机视觉-光源的目的和作用

光源的目的 机器视觉系统的核心是图像采集和图像处理&#xff0c;而光源则是影响图像水平的重要因素&#xff0c;通过适当的光源照明&#xff0c;使图像中的目标信息与背景信息得到更好的分离&#xff0c;可大大降低图像识别难度&#xff0c;提高系统的精度和可靠性。 对于机器…...

源码角度分析Java 循环中删除数据为什么会报异常

一、源码角度分析Java 循环中删除数据为什么会报异常 相信大家在之前或多或少都知道 Java 中在增强 for中删除数据会抛出&#xff1a;java.util.ConcurrentModificationException 异常&#xff0c;例如&#xff1a;如下所示程序&#xff1a; public class RmTest {public sta…...

leetCode 229. 多数元素 II + 摩尔投票法 + 进阶 + 优化空间

229. 多数元素 II - 力扣&#xff08;LeetCode&#xff09; 给定一个大小为 n 的整数数组&#xff0c;找出其中所有出现超过 ⌊ n/3 ⌋ 次的元素。 进阶&#xff1a;尝试设计时间复杂度为 O(n)、空间复杂度为 O(1)的算法解决此问题。 &#xff08;1&#xff09;哈希表 class …...

5 个编写高效 Makefile 文件的最佳实践

在软件开发过程中&#xff0c;Makefile是一个非常重要的工具&#xff0c;它可以帮助我们自动化构建、编译、测试和部署。然而&#xff0c;编写高效的Makefile文件并不是一件容易的事情。在本文中&#xff0c;我们将讨论如何编写高效的Makefile文件&#xff0c;以提高我们的开发…...

20231028刷题记录

P3381 【模板】最小费用最大流 Portal. sol. 注意 SPFA 找最小费用增广路时不要到终点就返回&#xff0c;因为到终点的路径可能有多条不能确定哪条是费用最小的。 P2740 [USACO4.2] 草地排水Drainage Ditches Portal. 最大流模板。 注意区分 N , M N,M N,M。 CF609D G…...

39 深度学习(三):tensorflow.data模块的使用(基础,可跳)

文章目录 data模块的使用基础api的介绍csv文件tfrecord data模块的使用 在训练的过程中&#xff0c;当数据量一大的时候&#xff0c;我们纯读取一个文件&#xff0c;然后每次训练都调用相同的文件&#xff0c;然后进行处理是很不科学的&#xff0c;或者说&#xff0c;当我们需…...

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 实验&#xff0c;主要包括阻塞和非阻塞简介、等待队列、轮询、…...

037-第三代软件开发-系统音量设置

第三代软件开发-系统音量设置 文章目录 第三代软件开发-系统音量设置项目介绍系统音量设置QML 实现C 实现 总结一下 关键字&#xff1a; Qt、 Qml、 volume、 声音、 GPT 项目介绍 欢迎来到我们的 QML & C 项目&#xff01;这个项目结合了 QML&#xff08;Qt Meta-Obj…...

Python 自动化详解(pyautogui)

文章目录 1 概述1.1 第三方库&#xff1a;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指令&#xff1a;打包解包&#xff0c;不打开它、直接看内容1.介绍2.使用 七、bc指令八、uname -r指令1.…...

SpringBoot内置工具类之断言Assert的使用与部分解析

先例举一个service的demo中用来验证参数对象的封装方法&#xff0c;使用了Assert工具类后是不是比普通的 if(xxx) { throw new RuntimeException(msg) } 看上去要简洁多了&#xff1f; 断言Assert工具类简介 断言是一个判断逻辑&#xff0c;用来检查不该发生的情况&#xff…...

可靠性+灵活性:电力载波技术在楼宇自控中的核心价值

可靠性灵活性&#xff1a;电力载波技术在楼宇自控中的核心价值 在智能楼宇的自动化控制中&#xff0c;电力载波技术&#xff08;PLC&#xff09;凭借其独特的优势&#xff0c;正成为构建高效、稳定、灵活系统的核心解决方案。它利用现有电力线路传输数据&#xff0c;无需额外布…...

深入理解JavaScript设计模式之单例模式

目录 什么是单例模式为什么需要单例模式常见应用场景包括 单例模式实现透明单例模式实现不透明单例模式用代理实现单例模式javaScript中的单例模式使用命名空间使用闭包封装私有变量 惰性单例通用的惰性单例 结语 什么是单例模式 单例模式&#xff08;Singleton Pattern&#…...

Rust 异步编程

Rust 异步编程 引言 Rust 是一种系统编程语言,以其高性能、安全性以及零成本抽象而著称。在多核处理器成为主流的今天,异步编程成为了一种提高应用性能、优化资源利用的有效手段。本文将深入探讨 Rust 异步编程的核心概念、常用库以及最佳实践。 异步编程基础 什么是异步…...

自然语言处理——循环神经网络

自然语言处理——循环神经网络 循环神经网络应用到基于机器学习的自然语言处理任务序列到类别同步的序列到序列模式异步的序列到序列模式 参数学习和长程依赖问题基于门控的循环神经网络门控循环单元&#xff08;GRU&#xff09;长短期记忆神经网络&#xff08;LSTM&#xff09…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量&#xff0c;这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

手机平板能效生态设计指令EU 2023/1670标准解读

手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读&#xff0c;综合法规核心要求、最新修正及企业合规要点&#xff1a; 一、法规背景与目标 生效与强制时间 发布于2023年8月31日&#xff08;OJ公报&…...

通过MicroSip配置自己的freeswitch服务器进行调试记录

之前用docker安装的freeswitch的&#xff0c;启动是正常的&#xff0c; 但用下面的Microsip连接不上 主要原因有可能一下几个 1、通过下面命令可以看 [rootlocalhost default]# docker exec -it freeswitch fs_cli -x "sofia status profile internal"Name …...

HTML前端开发:JavaScript 获取元素方法详解

作为前端开发者&#xff0c;高效获取 DOM 元素是必备技能。以下是 JS 中核心的获取元素方法&#xff0c;分为两大系列&#xff1a; 一、getElementBy... 系列 传统方法&#xff0c;直接通过 DOM 接口访问&#xff0c;返回动态集合&#xff08;元素变化会实时更新&#xff09;。…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

基于单片机的宠物屋智能系统设计与实现(论文+源码)

本设计基于单片机的宠物屋智能系统核心是实现对宠物生活环境及状态的智能管理。系统以单片机为中枢&#xff0c;连接红外测温传感器&#xff0c;可实时精准捕捉宠物体温变化&#xff0c;以便及时发现健康异常&#xff1b;水位检测传感器时刻监测饮用水余量&#xff0c;防止宠物…...