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

C語言手寫 atoi:字串轉整數完整實作與邊界處理

     編輯:關於C語言

C語言手寫 atoi:字串轉整數完整實作與邊界處理

atoi (ASCII to Integer) 是將字串轉換為整數的標準庫函數。手寫實作能深入理解字串解析、正負號處理、溢位檢測、非數字字符停止規則。本文提供標準版、健壯版(含錯誤回報)、strtol 風格完整版,並分析 INT_MIN 邊界陷阱。

標準版實作(教學用)

#include <stdio.h>

int my_atoi(char s[]) {
    int sign = 1;      // 正負號旗標
    int result = 0;
    char *p = s;

    // 1. 跳過前導空白 (標準 atoi 行為)
    while (*p == ' ' || *p == '\t' || *p == '\n') p++;

    // 2. 處理正負號
    if (*p == '-') {
        sign = -1;
        p++;
    } else if (*p == '+') {
        p++;
    }

    // 3. 累積數字
    while (*p >= '0' && *p <= '9') {
        result = result * 10 + (*p - '0');
        p++;
    }

    return sign * result;
}

int main() {
    char s[20];
    gets(s);  // 注意:gets 不安全,教學用
    int ret = my_atoi(s);
    printf("%d\n", ret);
    return 0;
}

健壯版:錯誤碼回報 + 溢位檢測

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

// 回傳碼:0=成功, -1=溢位, -2=無有效數字, -3=空指標
int my_atoi_robust(const char *str, long long *out) {
    if (!str) return -3;

    const char *p = str;
    // 跳過空白
    while (isspace(*p)) p++;

    // 正負號
    int sign = 1;
    if (*p == '-') { sign = -1; p++; }
    else if (*p == '+') { p++; }

    // 至少一個數字
    if (!isdigit(*p)) return -2;

    long long result = 0;
    while (isdigit(*p)) {
        int digit = *p - '0';

        // 溢位檢測:result * 10 + digit > LLONG_MAX
        if (result > (LLONG_MAX - digit) / 10) {
            return -1;  // 溢位
        }
        result = result * 10 + digit;
        p++;
    }

    *out = sign * result;
    return 0;
}

完整版:模仿 strtol 介面

輸入標準 atoi健壯版說明
"123"123123正常
"-456"-456-456負號
"  789"789789前導空白
"12abc"1212 (endptr 指向 a)非數字停止
"abc"0錯誤 -2無數字
"2147483648"UB (溢位)錯誤 -1 / LONG_MAXINT_MAX+1
"-2147483649"UB錯誤 -1 / LONG_MININT_MIN-1
""0錯誤 -2空字串
NULLCrash錯誤 -3空指標


INT_MIN 絕對值溢位陷阱

// INT_MIN = -2147483648
// 絕對值 2147483648 > INT_MAX (2147483647)
// 直接 -INT_MIN 導致有號整數溢位 (UB)

// 解決:使用長整型或無號型別計算
long long val = str;
if (val < 0) val = -val;  // long long 足夠容納

// 或:累積時用無號長整型
unsigned long long uval = 0;
while (isdigit(*p)) {
    uval = uval * 10 + (*p - '0');
    // 檢查 uval > (unsigned)LLONG_MAX ...
}
result = sign * (long long)uval;

標準庫 atoi vs strtol

  • atoi:簡單、無錯誤回報、溢位未定義行為、已棄用。
  • strtol:完整錯誤處理、支援任意基數 (2-36)、endptr 回傳解析結束位置、推薦使用。
  • strtoll / strtoull:64 位版本。

手寫 atoi 不只是面試題,更是理解「字串解析狀態機」、「有號整數溢位語義」、「API 設計權衡」的最佳切入點。建議實作健壯版並編寫完整單元測試覆蓋上述所有邊界案例。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved