strerror函數的詳細解析

一、strerror函數源碼

strerror函數是C標準庫中用來將errno值轉為可讀錯誤信息的函數。errno是系統和函數調用時產生的錯誤標識。strerror源碼如下:

char *strerror(int errnum)
{
    static char buf[BUF_SIZE]; //BUF_SIZE表示最大可用的錯誤字符串長度
    if (errnum = _sys_nerr || _sys_errlist[errnum] == NULL) {
        snprintf(buf, BUF_SIZE, "Unknown error %d", errnum); //若錯誤碼不在區間[0,_sys_nerr)中,則返回"Unknown error [錯誤碼]"
    } else {
        snprintf(buf, BUF_SIZE, "%s", _sys_errlist[errnum]); //否則返回對應錯誤碼的字符串
    }
    return buf;
}

該函數通過在全局變量_sys_errlist中查找對應錯誤碼的字符串,並將其拷貝到靜態的緩衝區buf中,返回buf的地址。如果不在可處理範圍內,則返回默認字符串「Unknown error [錯誤碼]」。

二、返回當前errno值

errno是一個宏,可用於在C程序中查詢函數調用的錯誤。errno在頭文件中定義。errno值反映上一次系統調用執行時發生的錯誤狀態。示例代碼如下:

#include 
#include 
#include 

int main() {
    FILE *fp;
    fp = fopen("non-existent-file.txt", "r"); // 將嘗試打開一個不存在的文件
    if (fp == NULL) {
        printf("打開文件失敗,錯誤碼:%d,錯誤信息:%s\n", errno, strerror(errno));
    } else {
        // 處理讀取文件的代碼
    }
    return 0;
}

上述代碼中,文件指針fp的值將為NULL,因為嘗試打開的文件不存在。此時,errno為2,對應常量為ENOENT,即No such file or directory。使用strerror函數將錯誤碼轉為錯誤信息字符串並輸出。

三、strerror函數頭文件

在使用strerror函數之前需要進行頭文件包含。strerror函數聲明在中,應當在源文件頂部加上以下語句:

#include 

四、strerror函數和perror

perror函數用於在標準錯誤流stderr上輸出錯誤信息,它將參數中的字符串和errno對應的錯誤信息一起輸出。perror函數的源碼如下:

void perror(const char *s)
{
    fprintf(stderr, "%s: %s\n", (s == NULL) ? "" : s, strerror(errno));
}

其中s是一個字符串,若非空,它將在錯誤信息前輸出。此外,strerror(errno)返回的是靜態內存空間的指針。perror函數直接輸出這個指針的內容到標準錯誤流中,所以可以直接使用perror輸出錯誤信息,代碼如下所示:

#include 
#include 

int main() {
    FILE *fp;
    fp = fopen("non-existent-file.txt", "r");
    if (fp == NULL) {
        perror("打開文件失敗");
    } else {
        // 處理讀取文件的代碼
    }
    return 0;
}

五、strreverse函數

strreverse函數會將字符串原址翻轉。源碼如下:

char *strreverse(char *str) {
    if (str == NULL) return NULL;
    unsigned int len = strlen(str);
    char temp;
    for (int i=0; i<len/2; i++) {
        temp = str[i];
        str[i] = str[len-i-1];
        str[len-i-1] = temp;
    }
    return str;
}

該函數先判斷了參數是否為NULL,可以避免出現引用空指針的情況。然後獲取了字符串長度len,使用交換的方式將前一半和後一半字符嚴格對稱的位置進行交換。最後返回原址。

六、strrchr函數

strrchr函數用於在一個字符串中查找一個給定的字符,返回該字符在字符串中最後一次出現的位置。如果未找到,函數返回NULL。源碼和示例代碼如下:

char *strrchr(const char *s, int c) {
    const char *last = NULL;
    do {
        if (*s == (char)c) {
            last = s;
        }
    } while (*s++ != '\0');
    return (char *)last;
}

#include 
#include 

int main() {
    char str[] = "Hello, world!";
    char *p = strrchr(str, 'o');
    if (p != NULL) {
        printf("最後一個o在%s的第%d個位置\n", str, p-str+1);
    } else {
        printf("未找到o字符\n");
    }
    return 0;
}

上述代碼中,char *p = strrchr(str, ‘o’)將返回最後一個字符o的位置,用指針p指向該位置,然後p-str+1得到字符在字符串中的位置。若未找到字符o,則返回NULL。

七、strrev函數

strrev函數用來翻轉一個字符串。源碼如下:

char *strrev(char *str) {
    if (str == NULL) return NULL;
    char *p1, *p2;
    p1 = str;
    p2 = str + strlen(str) - 1;
    while (p1 < p2) {
        char temp;
        temp = *p1;
        *p1 = *p2;
        *p2 = temp;
        p1++;
        p2--;
    }
    return str;
}

該函數使用雙指針迭代的方式將字符串頭和尾位置的字符依次進行交換。返回字符串原址。

八、strtrim函數

strtrim函數用於從字符串的首尾刪除空格字符(包括\t、\n、\v、\f、\r、空格)。

char *strtrim(char *str) {
    if (str == NULL) return NULL;
    int len = strlen(str);
    char *p1, *p2;
    p1 = str;
    while (*p1 != '\0' && isspace(*p1)) {
        p1++;
    }
    p2 = str + len - 1;
    while (p2 > p1 && isspace(*p2)) {
        p2--;
    }
    *(p2+1) = '\0';
    return p1;
}

該函數首先判斷字符串是否為NULL,然後使用指針p1找到字符串首部出現的第一個非空格字符位置。然後使用指針p2找到字符串尾部出現的第一個非空格字符位置的前一個位置,因為該字符直到該位置都應該保留,而不是實際刪除。刪除尾部空格的方法是將尾指針遞減直到p1之前,加上’\0’表示字符串的結束。最後返回字符串指向p1的指針。

結尾

本文詳細介紹了strerror函數及其相關函數的含義、源碼和使用。strerror函數可以將errno值轉換為可讀的錯誤信息字符串;errno表示了函數調用時返回的錯誤碼。strreverse、strrchr、strrev、strtrim函數分別用於字符串翻轉、查找最後一個字符位置、翻轉字符串、刪除首尾空格。熟練掌握這些函數可以使程序開發更加便捷和高效。

原創文章,作者:TCPCR,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/313273.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
TCPCR的頭像TCPCR
上一篇 2025-01-07 09:43
下一篇 2025-01-07 09:43

相關推薦

  • Python中引入上一級目錄中函數

    Python中經常需要調用其他文件夾中的模塊或函數,其中一個常見的操作是引入上一級目錄中的函數。在此,我們將從多個角度詳細解釋如何在Python中引入上一級目錄的函數。 一、加入環…

    編程 2025-04-29
  • Python中capitalize函數的使用

    在Python的字符串操作中,capitalize函數常常被用到,這個函數可以使字符串中的第一個單詞首字母大寫,其餘字母小寫。在本文中,我們將從以下幾個方面對capitalize函…

    編程 2025-04-29
  • Python中set函數的作用

    Python中set函數是一個有用的數據類型,可以被用於許多編程場景中。在這篇文章中,我們將學習Python中set函數的多個方面,從而深入了解這個函數在Python中的用途。 一…

    編程 2025-04-29
  • 單片機打印函數

    單片機打印是指通過串口或並口將一些數據打印到終端設備上。在單片機應用中,打印非常重要。正確的打印數據可以讓我們知道單片機運行的狀態,方便我們進行調試;錯誤的打印數據可以幫助我們快速…

    編程 2025-04-29
  • 三角函數用英語怎麼說

    三角函數,即三角比函數,是指在一個銳角三角形中某一角的對邊、鄰邊之比。在數學中,三角函數包括正弦、餘弦、正切等,它們在數學、物理、工程和計算機等領域都得到了廣泛的應用。 一、正弦函…

    編程 2025-04-29
  • Python3定義函數參數類型

    Python是一門動態類型語言,不需要在定義變量時顯示的指定變量類型,但是Python3中提供了函數參數類型的聲明功能,在函數定義時明確定義參數類型。在函數的形參後面加上冒號(:)…

    編程 2025-04-29
  • Python定義函數判斷奇偶數

    本文將從多個方面詳細闡述Python定義函數判斷奇偶數的方法,並提供完整的代碼示例。 一、初步了解Python函數 在介紹Python如何定義函數判斷奇偶數之前,我們先來了解一下P…

    編程 2025-04-29
  • Python實現計算階乘的函數

    本文將介紹如何使用Python定義函數fact(n),計算n的階乘。 一、什麼是階乘 階乘指從1乘到指定數之間所有整數的乘積。如:5! = 5 * 4 * 3 * 2 * 1 = …

    編程 2025-04-29
  • 分段函數Python

    本文將從以下幾個方面詳細闡述Python中的分段函數,包括函數基本定義、調用示例、圖像繪製、函數優化和應用實例。 一、函數基本定義 分段函數又稱為條件函數,指一條直線段或曲線段,由…

    編程 2025-04-29
  • Python函數名稱相同參數不同:多態

    Python是一門面向對象的編程語言,它強烈支持多態性 一、什麼是多態多態是面向對象三大特性中的一種,它指的是:相同的函數名稱可以有不同的實現方式。也就是說,不同的對象調用同名方法…

    編程 2025-04-29

發表回復

登錄後才能評論