提卡网站怎么做,兖矿东华建设网站,网站源代码上传,雅安网站制作strerror 和 errno 详解
printf(Error: %s\n, strerror(errno));这行代码用于在 C 语言中输出系统错误信息#xff0c;但它与 Windows 的 GetLastError() 有重要区别。下面我将详细解释每个部分及其工作原理。
1. 组件解析
errno
定义#xff1a;errno 是一个…strerror 和 errno 详解
printf(Error: %s\n, strerror(errno));这行代码用于在 C 语言中输出系统错误信息但它与 Windows 的 GetLastError() 有重要区别。下面我将详细解释每个部分及其工作原理。
1. 组件解析
errno
定义errno 是一个全局整型变量在 C11 标准中改为线程局部存储定义在 errno.h 头文件中作用存储标准 C 库函数执行失败时的错误代码特点 由标准 C 库函数设置如文件操作、内存分配等不是 Windows API 错误Windows API 使用 GetLastError()在多线程环境中现代编译器通常将其实现为线程安全的
strerror
原型char *strerror(int errnum);作用将错误代码转换为可读的错误描述字符串参数接收一个错误码通常是 errno 的值返回值指向静态分配的字符串的指针描述错误信息
2. 典型使用场景
#include stdio.h
#include errno.h
#include string.hint main() {FILE *fp fopen(nonexistent.txt, r);if (fp NULL) {printf(Error: %s\n, strerror(errno));// 或使用 perror 更简单的方式perror(Failed to open file);}return 0;
}3. 与 Windows API GetLastError() 的区别
特性errno/strerrorGetLastError()/FormatMessage来源标准 C 库函数设置Windows API 函数设置头文件errno.h, string.hwindows.h错误码范围标准 C 定义的错误码Windows 系统错误码线程安全现代实现中是线程安全的本身就是线程特定的典型错误示例ENOENT(2): 文件不存在ERROR_FILE_NOT_FOUND(2): 系统找不到文件获取字符串的函数strerror()FormatMessage()
4. 常见问题
问题1为什么我的 Windows API 错误用 strerror 显示不正确
原因Windows API 错误应该使用 GetLastError() FormatMessage()示例// 错误方式不适用于Windows API错误
CloseHandle(invalid_handle);
printf(%s\n, strerror(errno)); // 不会显示正确的Windows错误// 正确方式
CloseHandle(invalid_handle);
printf(Error: %d\n, GetLastError()); // 使用FormatMessage更好问题2errno 的值何时会被覆盖
规则 成功的库函数调用不会修改 errno标准规定某些实现可能在成功调用时将 errno 设为 0应该立即在函数调用失败后检查 errno
问题3strerror 的返回值有效期是多久
答案 返回指向静态字符串的指针不需要释放但后续调用可能会覆盖该内容非线程安全实现中在 C11 中可以使用 strerror_s 更安全的版本
5. 替代方案
(1) perror() - 更简单的打印方式
fopen(nonexistent.txt, r);
if (errno) {perror(File open failed); // 输出: File open failed: No such file or directory
}(2) strerror_r (线程安全版本, POSIX)
char buf[256];
strerror_r(errno, buf, sizeof(buf));
printf(Error: %s\n, buf);(3) C11 的 strerror_s
char buf[256];
strerror_s(buf, sizeof(buf), errno);
printf(Error: %s\n, buf);6. 典型 errno 错误码示例
错误码值描述EPERM1操作不允许ENOENT2文件或目录不存在EIO5输入/输出错误EBADF9错误的文件描述符EAGAIN11资源暂时不可用请重试EACCESS13权限不足EFAULT14错误的地址EBUSY16设备或资源忙EEXIST17文件已存在EINVAL22无效参数ENOSPC28设备无剩余空间
7. 最佳实践建议 在 Windows 编程中 对于 Win32 API 错误始终使用 GetLastError() FormatMessage()对于标准 C 库函数可以使用 errno strerror() 跨平台编程 #ifdef _WIN32
// Windows 错误处理
#else
// POSIX 错误处理
#endif错误处理模板 #include stdio.h
#include errno.h
#include string.hvoid print_error(const char *context) {#ifdef _WIN32DWORD error GetLastError();LPSTR buffer NULL;FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,NULL, error, 0, (LPSTR)buffer, 0, NULL);fprintf(stderr, %s: %s (code %d)\n, context, buffer, error);LocalFree(buffer);#elsefprintf(stderr, %s: %s (code %d)\n, context, strerror(errno), errno);#endif
}理解这些区别对于正确诊断和报告系统错误至关重要特别是在混合使用标准库函数和平台特定API时。