一、errno perror strerror的使用

秋雨无痕發表於2024-07-01

在Linux中,errno是一個非常重要的全域性變數,用於儲存系統呼叫的錯誤程式碼。

以下是關於errno的詳細解釋:

定義和用途

1.errno是一個預定義的外部整型(int)變數,通常包含在<errno.h>標頭檔案中。

2.當系統呼叫或庫函式發生錯誤時,它們通常會設定errno以指示發生了哪種錯誤。

3.errno的值僅在函式失敗時才會被設定,並且會覆蓋之前的值。

4.透過檢查errno的值,程式設計師可以確定發生了什麼錯誤,並據此編寫適當的錯誤處理程式碼。

在 /usr/include/asm-generic/errno-base.h 中記錄著errno對應的錯誤資訊

  4#define EPERM    1  /* Operation not permitted */
  5 #define ENOENT     2  /* No such file or directory */
  6 #define ESRCH    3  /* No such process */
  7 #define EINTR    4  /* Interrupted system call */
  8 #define EIO    5  /* I/O error */
  9 #define ENXIO    6  /* No such device or address */
 10 #define E2BIG    7  /* Argument list too long */
 11 #define ENOEXEC    8  /* Exec format error */
 12 #define EBADF    9  /* Bad file number */
 13 #define ECHILD    10  /* No child processes */
 14 #define EAGAIN    11  /* Try again */
 15 #define ENOMEM    12  /* Out of memory */
 16 #define EACCES    13  /* Permission denied */
 17 #define EFAULT    14  /* Bad address */
 18 #define ENOTBLK   15  /* Block device required */
 19 #define EBUSY   16  /* Device or resource busy */
 20 #define EEXIST    17  /* File exists */
 21 #define EXDEV   18  /* Cross-device link */
 22 #define ENODEV    19  /* No such device */
 23 #define ENOTDIR   20  /* Not a directory */
 24 #define EISDIR    21  /* Is a directory */
 25 #define EINVAL    22  /* Invalid argument */
 26 #define ENFILE    23  /* File table overflow */
 27 #define EMFILE    24  /* Too many open files */
 28 #define ENOTTY    25  /* Not a typewriter */
 29 #define ETXTBSY   26  /* Text file busy */
 30 #define EFBIG   27  /* File too large */
 31 #define ENOSPC    28  /* No space left on device */
 32 #define ESPIPE    29  /* Illegal seek */

使用示例

  • 在C程式中,如果某個系統呼叫或庫函式呼叫失敗,並且你想檢查失敗的原因,你應該在呼叫後立即檢查errno的值。
  • 需要注意的是,由於errno的值可能會被後續的系統呼叫或庫函式呼叫覆蓋,所以你應該在函式失敗後立即檢查它的值。
 1 #include<stdio.h>
 2 #include <errno.h>
 3 int main()
 4 {
 5     FILE*fp;
 6     fp = fopen("temp","r");
 7     if(fp == NULL)
 8     {
 9         fprintf(stderr,"fopen() failed! errno = %d\n",errno);
10         exit(1);
11     }
12     puts("OK!");
13     exit(0);
14 }

示例中我們試圖以只讀方式開啟一個不存在的檔案。

執行結果:

fopen() failed! errno = 2

可以看到errno = 2,對應上面的為

 #define ENOENT     2  /* No such file or directory */
直接使用errno存在一個缺陷,因為errno是一個整型數值,需要查詢才能確定錯誤資訊,我們可做如下改進:使用perror()
示例如下:
 1 #include<stdio.h>
 2 #include <errno.h>
 3 int main()
 4 {
 5     FILE*fp;
 6     fp = fopen("temp","r");
 7     if(fp == NULL)
 8     {
 9         //fprintf(stderr,"fopen() failed! errno = %d\n",errno);
10         perror("fopen() failed!");
11         exit(1);
12     }
13     puts("OK!");
14     exit(0);
15 }

這樣可以直接輸出錯誤資訊,輸出結果如下:

fopen() failed!: No such file or directory

或者使用strerror

示例如下:

 1 #include<stdio.h>
 2 #include <errno.h>
 3 #include <string.h>
 4 
 5 int main()
 6 {
 7     FILE*fp;
 8     fp = fopen("temp","r");
 9     if(fp == NULL)
10     {
11         //fprintf(stderr,"fopen() failed! errno = %d\n",errno);
12         //perror("fopen() failed!");
13        fprintf(stderr,"fopen() failed! errno = %s\n",strerror(errno));
14         exit(1);
15     }
16     puts("OK!");
17     exit(0);
18 }

執行結果:

fopen() failed! errno = No such file or directory

相關文章