首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Linux C 庫函數大全:字符串處理函數(atof/atoi/strtod/strtol/gcvt/toascii 等)詳解與實例

     編輯:關於C語言

字符串與數值互轉是 C 程式最高頻操作之一。標準庫提供了 atof/atoi/atol 簡易族與 strtod/strtol/strtoul 健壯族、gcvt/ecvt/fcvt 浮點轉字符串、toascii/tolower/toupper 字符映射等函數。本文逐一解析原型、行為差異、錯誤處理並給出可編譯實例。

一、簡易轉換族(不推薦生產環境)

函數原型返回缺陷
atofdouble atof(const char *nptr)double無錯誤報告,溢出行為未定義
atoiint atoi(const char *nptr)int同上,等價 strtol(nptr,NULL,10)
atollong atol(const char *nptr)long同上,等價 strtol(nptr,NULL,10)

建議:僅用於快速原型/教學,**生產代碼請改用 strto* 族**。

二、健壯轉換族 strto*(首選)

double strtod(const char *nptr, char **endptr);
long   strtol(const char *nptr, char **endptr, int base);
unsigned long strtoul(const char *nptr, char **endptr, int base);

核心優勢

  1. 錯誤定位:endptr 指向第一個無效字符,可精確判斷解析範圍。
  2. 進制自適應:base=0 時自動識別 0x(16進制)、0(8進制)、其餘(10進制)。
  3. 溢出檢測:設置 errno=ERANGE 並返回 HUGE_VAL/LONG_MAX/ULONG_MAX。
  4. 線程安全:無靜態內部狀態。

實例:安全解析用戶輸入的整數

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <limits.h>

long safe_strtol(const char *s, int base, int *ok) {
    char *end;
    errno = 0;
    long val = strtol(s, &end, base);
    if (errno == ERANGE || end == s || *end != '\0') {
        *ok = 0;
        return 0;
    }
    *ok = 1;
    return val;
}

int main(void) {
    int ok;
    printf("%ld\n", safe_strtol("123", 10, &ok));   // 123, ok=1
    printf("%ld\n", safe_strtol("0xFF", 0, &ok));   // 255, ok=1
    printf("%ld\n", safe_strtol("9999999999999", 10, &ok)); // 0, ok=0 (溢出)
    return 0;
}

三、浮點數 → 字符串(gcvt/ecvt/fcvt)

函數特點備註
gcvt結果含小數點/符號,四捨五入到指定有效位數緩衝區由調用者分配
ecvt科學計數法,無小數點,返回靜態緩衝區指針非線程安全
fcvt定點格式,無小數點,返回靜態緩衝區指針非線程安全

現代替代:snprintf(buf, sizeof(buf), "%.*g", prec, val) 或 C++ std::to_chars (C++17)。

四、字符映射函數

  • int toascii(int c):c & 0x7F,將任意值壓縮為 7-bit ASCII。
  • int tolower(int c) / toupper(int c):僅轉換字母,其他字符原樣返回。需包含 <ctype.h>。
  • 陷阱:參數為 EOF 或負值時行為未定義,**必須轉為 unsigned char 後傳入**:tolower((unsigned char)ch)。

五、綜合實例:迷你計算器解析器

/* 解析 "3.14 + 2" 形式的簡單表達式 */
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <errno.h>

int main(void) {
    char line[256];
    while (fgets(line, sizeof(line), stdin)) {
        char *p = line;
        while (isspace((unsigned char)*p)) ++p;
        int ok1, ok2;
        double a = strtod(p, &p);
        if (!ok1) continue;
        while (isspace((unsigned char)*p)) ++p;
        char op = *p++;
        while (isspace((unsigned char)*p)) ++p;
        double b = strtod(p, &p);
        if (!ok2) continue;

        double res = (op=='+')?a+b:(op=='-')?a-b:(op=='*')?a*b:(op=='/')?a/b:0;
        printf("= %g\n", res);
    }
    return 0;
}
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved