十六進制為基數 16 位置制,數字 0-9、字母 A-F(或 a-f)分別代表 0~15。第 N 位(從右起 0)權值為 16^N。例:0x2AF5 = 2×16³ + 10×16² + 15×16¹ + 5×16⁰ = 10997。
#include
#include
#include
#include
long hex_to_long(const char *str) {
char *endptr;
errno = 0;
long val = strtol(str, &endptr, 16); // 基數 16
if (errno == ERANGE) { perror("溢位"); return LONG_MAX; }
if (endptr == str) { fprintf(stderr, "無效格式\n"); return 0; }
if (*endptr != '\0') { fprintf(stderr, "尾部垃圾字符: %s\n", endptr); }
return val;
}
int main() {
printf("%ld\n", hex_to_long("2AF5")); // 10997
printf("%ld\n", hex_to_long("-1A")); // -26
printf("%ld\n", hex_to_long("0xFF")); // 255 (支援 0x 前綴)
return 0;
}
strtol/strtoul/strtoll 自動處理空白、正負號、0x 前綴、大小寫。endptr 可精確檢測解析位置與錯誤。#include
#include
uint32_t hex_to_u32_manual(const char *s) {
uint32_t result = 0;
while (*s) {
char c = *s++;
uint32_t digit;
if (c >= '0' && c <= '9') digit = c - '0';
else if (c >= 'A' && c <= 'F') digit = c - 'A' + 10;
else if (c >= 'a' && c <= 'f') digit = c - 'a' + 10;
else break; // 遇到非十六進制字符停止
result = (result << 4) | digit; // 乘 16 相當於左移 4 位
}
return result;
}
關鍵技巧:result = (result << 4) | digit 替代乘法,效率更高。
int parse_hex_int32(const char *str, int32_t *out) {
if (!str) return -1;
// 跳過空白
while (isspace(*str)) str++;
// 處理符號
int neg = 0;
if (*str == '-') { neg = 1; str++; }
else if (*str == '+') str++;
// 跳過 0x/0X
if (str[0] == '0' && (str[1] == 'x' || str[1] == 'X')) str += 2;
uint32_t val = 0;
for (; *str; str++) {
char c = *str;
uint32_t d;
if (c >= '0' && c <= '9') d = c - '0';
else if (c >= 'A' && c <= 'F') d = c - 'A' + 10;
else if (c >= 'a' && c <= 'f') d = c - 'a' + 10;
else break;
// 溢位檢測:val > (UINT32_MAX - d) / 16
if (val > (UINT32_MAX - d) >> 4) return -2; // 溢位
val = (val << 4) | d;
}
if (neg) {
if (val > (uint32_t)INT32_MAX + 1) return -2;
*out = -(int32_t)val;
} else {
if (val > INT32_MAX) return -2;
*out = (int32_t)val;
}
return 0;
}
reg write 0x4000 0xFF)。#RRGGBB → RGB 分量)。strtoul/strtoll,健壯、標準、無需造輪子。