标准C库函数之perror()、strerror(),以及他们之间各种的优缺点(打印错误信息)
前言
如果,想要深入的学习标准C库中perror、strerror函数,还是需要去自己阅读Linux系统中的帮助文档。
具体输入命令:
man 3 perror
man 3 strerror
即可查阅到完整的资料信息。
perror函数
perror函数是C语言标准库中的一个函数,
用于在发生系统调用错误时输出有关错误信息的描述。
该函数定义在stdio.h
头文件中。perror根据传入的参数(通常是一个字符串)生成一个描述性的错误消息,然后将这个消息输出到标准错误流(stderr)。
函数原型如下:
#include <stdio.h> //使用此函数需引入此头文件void perror(const char *str);
参数:
- str:一个指向常量字符的指针,用于提供上下文信息。
在输出错误消息时,这个字符串将作为错误消息的前缀
(也就是说,你可以手动的去描述这个错误是怎么发生的)。
perror的工作原理:当一个系统调用或库函数发生错误时,通常会将全局变量errno
设置为一个特定的错误码。perror函数读取errno的值,并根据这个值生成相应的错误描述。然后,将错误描述与传入的字符串参数拼接,并输出到标准错误流。
使用示例:
#include <stdio.h>
#include <stdlib.h>int main() {FILE *file_ptr;file_ptr = fopen("non_existent_file.txt", "r");if (file_ptr == NULL) {perror("Error opening file");return 1;}// ... 其他操作 ...fclose(file_ptr);return 0;
}
在上面的示例中,当试图打开一个不存在的文件时,fopen函数会返回NULL,并将errno设置为一个特定的错误码。
调用perror函数输出类似于以下内容的错误消息:
Error opening file: No such file or directory
这里的"Error opening file"是传入的字符串参数,而"No such file or directory"是由perror根据errno值生成的描述性错误信息。
strerror 函数
strerror函数是标准C库中的一种函数,它用于生成描述错误代码的字符串。这个函数在string.h头文件中定义。
这个函数的原型是:
#include <string.h> //使用此函数需引入此头文件char *strerror(int errnum);
参数:
- 该函数接受一个
整数errnum作为参数
,这个参数通常是一个错误代码,比如你可能从某些函数(如open或read)中得到这样的错误代码。
返回值:
- 函数
会返回一个指向描述该错误的字符串的指针
。这个字符串可以用来打印错误消息,使得用户能够理解发生了什么问题。
例如,你可以这样使用strerror:
#include <stdio.h>
#include <string.h>
#include <errno.h>int main() {FILE *file = fopen("non_existent_file.txt", "r");if (file == NULL) {printf("打开文件出错: %s\n", strerror(errno));return 1;}// 做一些处理fclose(file);return 0;
}
在这个例子中,如果文件不存在,fopen会返回NULL,并将errno设置为表示错误的值。然后,我们可以使用strerror来获取并打印描述这个错误的消息。
需要注意的是,strerror返回的字符串是静态分配的,不需要(也不应该)被手动释放。此外,因为strerror返回的是静态数据,所以它不是线程安全的。在多线程环境中,你可能需要使用strerror_r,这个函数有一个额外的参数用于存储结果,可以避免竞态条件。
另外,也应该注意strerror可能不会知道所有可能的错误代码。如果你传递一个它不认识的错误代码,它可能会返回一个消息说这个错误未知。
strerror()函数与perror()函数各种的优缺点
strerror
优点:
灵活性
:strerror返回一个字符串,这使得你可以自由地使用这个字符串。例如,你可以将其存储,发送给用户,或者记录到日志中。自定义错误消
息:可以通过与其他字符串拼接,创建定制的错误消息。
缺点:
需要手动处理错误消息:在打印错误消息时,需要手动处理错误消息的格式化和输出。
非线程安全
:strerror在多线程环境中可能会产生问题,因为它返回静态内存中的字符串。如果你需要线程安全,需要使用strerror_r版本。
perror
优点:
简单易用
:perror在打印错误消息时无需处理错误消息的格式化和输出,使得错误处理代码更加简洁。自动生成错误消息
:它自动地在你提供的自定义消息后添加一个描述错误的消息。
缺点:
不够灵活
:perror总是将错误消息输出到标准错误输出。如果你需要将错误消息发送到其他地方,你就无法使用perror。缺乏自定义
:虽然你可以提供自定义消息,但perror控制的消息格式有限。如果你需要更特殊的格式,可能需要使用strerror。
总的来说,选择使用哪一个函数取决于你的需求。如果你需要处理错误消息,例如将其发送到特定的日志系统,或者创建定制的错误消息,那么strerror可能是更好的选择。如果你只需要快速地向用户报告错误,并且默认的格式足够好,那么perror可能是更好的选择。
strerror_r 函数
strerror_r函数是标准C库中的另一种处理错误的函数,它与strerror函数类似,但具有线程安全性。
- 在标准C库中,strerror_r函数有两个不同的实现:
POSIX和GNU
。它们具有不同的原型和行为,我将分别介绍它们。
POSIX版本的strerror_r
POSIX版本的strerror_r的原型如下:
int strerror_r(int errnum, char *buf, size_t buflen);
这个函数接受三个参数:
- errnum:错误码。
- buf:用于存储错误消息的缓冲区。
- buflen:缓冲区的大小。
返回值
函数的返回值是一个整数,表示操作的成功与否。如果返回值为0,表示成功获取错误消息;如果返回值为正数,表示错误码无效,无法获取错误消息;如果返回值为负数,表示发生了错误。
需要注意的是,POSIX版本的strerror_r函数的行为和strerror函数略有不同。它不返回一个静态字符串指针,而是将错误消息复制到提供的缓冲区中。因此,这个函数是线程安全的,因为它使用了用户提供的缓冲区。
GNU版本的strerror_r
GNU版本的strerror_r的原型如下:
char *strerror_r(int errnum, char *buf, size_t buflen);
这个函数接受三个参数:
- errnum:错误码。
- buf:用于存储错误消息的缓冲区。
- buflen:缓冲区的大小。
返回值
函数的返回值是一个指向错误消息字符串的指针。与strerror函数不同,GNU版本的strerror_r并不返回静态分配的字符串,而是将错误消息复制到提供的缓冲区中,并返回指向缓冲区的指针。
这个版本的strerror_r在多线程环境中是安全的,因为它将错误消息存储在用户提供的缓冲区中,而不是使用静态内存。
需要注意的是,GNU版本的strerror_r与POSIX版本的返回类型和行为不同。在GNU版本中,返回值始终是指向错误消息字符串的指针,不论操作是否成功。
使用哪个版本取决于在编译时使用的特性测试宏。如果定义了 _POSIX_C_SOURCE,则使用 XSI-compliant version,否则使用 GNU-specific version。这也是为什么 strerror_r 函数在不同的系统和设置中可能有不同的行为。
总结
在我们的讨论中,我们涉及了以下内容:
strerror函数:它是标准C库中的函数,用于生成描述错误代码的字符串。它接受一个错误码作为参数,并返回一个描述错误的字符串。这个字符串可以用于打印错误消息或其他需要错误描述的场景。
perror函数:它也是标准C库中的函数,用于报告错误消息。它会打印你提供的自定义消息,后跟一个冒号、一个空格,然后是描述当前错误的消息。它的优点是简单易用,适用于快速报告错误的场景。
strerror_r函数:它是标准C库中的函数,用于获取描述错误代码的字符串,同时具备线程安全性。它有两个不同的实现:POSIX和GNU。POSIX版本将错误消息复制到用户提供的缓冲区中,并返回一个表示操作成功与否的整数。而GNU版本将错误消息复制到用户提供的缓冲区中,并返回指向缓冲区的指针。
总体而言,strerror函数和strerror_r函数用于获取描述错误的字符串,而perror函数用于报告错误消息。选择使用哪个函数取决于你的需求和编程环境,例如需要灵活性、自定义错误消息还是线程安全性。
最后的最后,如果你觉得我的这篇文章写的不错的话,请给我一个赞与收藏,关注我,我会继续给大家带来更多更优质的干货内容
。
标准C库函数之perror()、strerror(),以及他们之间各种的优缺点(打印错误信息)相关推荐
- linux c 打印错误信息error errno perror和strerror的区别
1 perror 头文件:stdio.h void perror(const char *msg); 它是基于errno的当前值,在标准错上产生一条出错信息,然后返回. 它先输出由msg字符串 ...
- 详解:strerror函数:将错误码转化为错误信息
对于大家在浏览网页的时候,或多或少的会见识过不少的错误信息:比如:最常见的就是:404 但是,使用strerror函数,可以将错误码转化为错误信息!不知道偶然间看见的读者是否有兴趣进行深入研究一下,本 ...
- C语言错误信息报告函数strerror、perror的使用
strerror char * strerror ( int errnum ); 返回错误码,所对应的错误信息.(是把错误码转化为对应的错误信息) #include <errno.h>// ...
- C语言函数:错误信息打印函数,strerror()与perror()
C语言函数:错误信息打印函数,strerror()与perror() strerror: C语言函数: 字符串函数及模拟实现strtok().strstr().strerror()_srhqwe的博客 ...
- c标准基本库函数:libc、glibc的关系
glibc 和 libc 都是 Linux 下的 C 函数库. libc 是 Linux 下的 ANSI C 函数库:glibc 是 Linux 下的 GUN C 函数库. ANSI C 和 GNU ...
- 假设成年人的体重和身高存在此种关系: 身高(厘米)-100=标准体重(千克) 如果一个人的体重与其标准体重的差值在正负5%之间,显示“体重正常”,其他则显示“体重超标”。编写程序,能处理用户输入的
2.假设成年人的体重和身高存在此种关系: 身高(厘米)-100=标准体重(千克) 如果一个人的体重与其标准体重的差值在正负5%之间,显示"体重正常",其他则显示"体重超标 ...
- C/C++错误分析errno,perror,strerror和GetLastError()函数返回的错误代码的意义
在C语言编译中,经常会出现一些系统的错误,这些错误如果在编译的时候不能很好的"预见",会使系统"崩溃",常见的捕获错误函数有: errno #include&l ...
- Linux标准IO定位函数,Linux C标准IO库函数详解 一
1.open/close函数 open函数可以打开或者创建一个文件. #include #include #include int open(const char *pathname, int fla ...
- 什么是Linux系统调用system call?(Linux内核中设置的一组用于实现各种系统功能的子程序)(区别于标准C库函数调用)核心态和用户态的概念、中断的概念、系统调用号、系统调用表
文章目录 什么是系统调用? 为什么要用系统调用? 系统调用是怎么工作的? 如何使用系统调用? _syscall*()是什么? errno是什么? 调用性能问题 Linux系统调用列表 进程控制 文件系 ...
最新文章
- Windows Azure AppFabric概述
- tarjan算法_【朝夕的ACM笔记】树上问题-最近公共祖先-倍增算法
- 【Python基础】推荐几个神器来拯救奇丑无比的python代码
- node.js介绍及Win7环境安装测试(转)
- 计算机mooc操作测试视频,计算机基础课MOOC视频的制作方法.doc
- 高效程序员的45个习惯 pdf_如何培养孩子高效学习?养成高效学习的7 个习惯。建议收藏...
- WebSocket-nodejs实现
- python 生成排列、组合以及选择
- python网易云_用python爬虫爬取网易云音乐
- 并行执行,没用到过,写到这里免得搞忘
- MFC编译出来的程序不能在其他机器上用
- mysql blob图片_显示存储在mysql blob中的图像
- 编程基础(三)——体系结构之二
- Xgboost中特征重要性计算方法详解
- 解压文件时,系统找不到指定路径
- 土地日度交易数据2000-2022
- php使用excel公式,使用PHPExcel上的公式问题(Excel2007)
- 网康NS-NGFW防火墙远程RCE 漏洞复现
- 面向Web开发人员和网站管理员的Web缓存指南
- uiautomator2+python实现企业微信自动打卡