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

C 語言字符串轉數字全攻略:atoi/strtol/strtoul 族函數詳解與溢出處理

     編輯:關於C語言

C 標準庫提供多套字符串轉數字函數,功能從簡單到強大。本文系統對比 atoi/atol/atof 與 strtol/strtoul/strtod 族,重點講解錯誤檢測、溢出處理、進制支持。

1. 簡易轉換函數(無錯誤檢測)

函數返回類型頭文件示例
atoiintstdlib.hatoi("123") → 123
atollongstdlib.hatol("1234567890")
atofdoublestdlib.hatof("3.14") → 3.14

⚠️ 缺陷:無法區分「轉換結果為 0」與「轉換失敗」,溢出行為未定義。

2. 強健轉換函數族(推薦)


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);
  • endptr:輸出參數,指向第一個未被轉換的字符
  • base:進制(2-36),0 表示自動檢測(0x 十六進制、0 八進制、其他十進制)
  • 返回值:轉換結果
  • 溢出:設置 errno = ERANGE,返回 LONG_MAX/MIN 或 ULONG_MAX

3. 實戰:溢出檢測與殘餘字符處理


char* str = "1234567891011121314151617181920"; // 超出 unsigned long
unsigned long num;
char* leftover;
errno = 0;
num = strtoul(str, &leftover, 10);

if (errno == ERANGE) {
    printf("溢出!最大值:%lu\n", ULONG_MAX);
    printf("未轉換部分:%s\n", leftover);
}

4. 進制轉換實戰


strtol("0xfea593ee", NULL, 0);  // 自動識別 16 進制 → 4271436782
strtol("fea593ee", NULL, 16);    // 顯式 16 進制
strtoul("fea593ee", NULL, 16);   // 無符號,避免符號位誤判

💡 strtol 處理高位為 1 的 16 進制數會當作負數(符號擴展),16 進制轉換首選 strtoul。

5. 完整錯誤檢測模板


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

6. C++11 現代替代


std::stoi("123");        // 拋出異常可捕獲
std::stol("123", nullptr, 16);
std::stod("3.14");
std::from_chars(ptr, ptr+len, val); // C++17 無異常、高性能

總結

  • 簡單場景可用 atoi 族
  • 生產代碼必須用 strtol/strtoul/strtod:支持錯誤檢測、溢出處理、進制自動識別、殘餘字符定位
  • 16 進制無符號轉換用 strtoul
  • C++ 優先用 std::from_chars(高性能、無異常、無 locale 開銷)
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved