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

C語言任意進制轉換:長整數轉指定基數帶符號字符串實現

     編輯:關於C語言

功能需求

  • 支持 2~36 進制轉換。
  • 正數/零前綴 +,負數前綴 -。
  • 8 進制前綴 0,16 進制前綴 0x/0X(可選大小寫)。
  • 緩衝區溢出檢查,失敗返回 NULL。

核心實現


#define LOW_CASE_NUM 0
#define UP_CASE_NUM  1
#define MAX_STR_SIZE 128

// 輔助:除法取餘並更新被除數
static inline long num_div(long *n, int base) {
    long r = *n % base;
    *n /= base;
    return r;
}

char *num_to_str(long num, int base, int case_sel, char *buf, size_t bufsz) {
    if (base < 2 || base > 36) return NULL;

    const char *digits = case_sel ? "0123456789abcdefghijklmnopqrstuvwxyz"
                                  : "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    char sign = (num < 0) ? (num = -num, '-') : '+';
    char tmp[MAX_STR_SIZE];
    int i = 0;

    tmp[i++] = '\0'; // 字符串結束符佔位
    if (num == 0) {
        tmp[i++] = '0';
    } else {
        while (num) tmp[i++] = digits[num_div(&num, base)];
    }

    // 添加進制前綴(低位在前,逆序構建)
    switch (base) {
        case 16: tmp[i++] = digits[33]; // 'x' 或 'X' (digits[33]='x', [34]='X' 需調整)
                 // 修正:直接用字面量更清晰
                 tmp[i++] = case_sel ? 'x' : 'X';
        case 8:  tmp[i++] = '0';
                 break;
    }
    tmp[i++] = sign; // 符號最後放(最高位)

    if (i >= (int)bufsz) return NULL; // 溢出檢查

    // 逆序複製到目標緩衝區
    for (int j = 0; i >= 0; ++j, --i)
        buf[j] = tmp[i];
    return buf;
}

測試用例與輸出


int main() {
    char buf[MAX_STR_SIZE];
    char *p;
    p = num_to_str(333, 16, LOW_CASE_NUM, buf, sizeof(buf));  // +0x14D
    p = num_to_str(-333, 16, UP_CASE_NUM, buf, sizeof(buf));   // -0X14D
    p = num_to_str(333, 8, LOW_CASE_NUM, buf, sizeof(buf));    // +0515
    p = num_to_str(-333, 2, LOW_CASE_NUM, buf, sizeof(buf));   // -101001101
    p = num_to_str(-333, 10, LOW_CASE_NUM, buf, sizeof(buf));  // -333
}

設計亮點

  1. 逆序構建:從低位向高位提取數字,自然避免了「先求長度再填充」的雙遍歷。
  2. 統一緩衝區:臨時數組 tmp 構建後一次性逆序複製,代碼緊湊。
  3. 參數校驗:基數範圍、緩衝區大小、符號處理完備。
  4. 大小寫可控:通過字符表選擇實現。

改進建議

  • 16 進制前綴邏輯略顯生硬(digits[33] 依賴具體字符表佈局),建議改為 case_sel ? 'x' : 'X'。
  • 可擴展支持 unsigned long、long long 及自定義前綴風格(如無前綴、# 前綴)。
  • 生產代碼建議加入 static assert 確保 MAX_STR_SIZE 足夠(64 位二進制含符號前綴需 66 字節)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved