K&R《C程序設計語言》練習2-3要求編寫函數htoi(s),將十六進制字符串(可選前綴0x/0X)轉換為等價整數值。原書答案假設輸入字符串開頭即為合法十六進制字符,否則返回0,通用性受限。
int htoi(char s[]) {
int hexdigit, i, inhex, n;
i = 0;
if (s[i] == '0') {
++i;
if (s[i] == 'x' || s[i] == 'X') ++i;
}
n = 0; inhex = 1;
for (; inhex; ++i) {
if (s[i] >= '0' && s[i] <= '9') hexdigit = s[i] - '0';
else if (s[i] >= 'a' && s[i] <= 'f') hexdigit = s[i] - 'a' + 10;
else if (s[i] >= 'A' && s[i] <= 'F') hexdigit = s[i] - 'A' + 10;
else inhex = 0;
if (inhex) n = 16 * n + hexdigit;
}
return n;
}
缺陷:若輸入"abc0x1F",函數直接返回0,無法跳過前導無效字符。
0x/0X在處理前添加循環掃描,僅當發現0x/0X時才開始轉換,否則跳過無效字符:
int htoi(char s[]) {
int hexdigit, i, inhex, n;
i = 0;
// 掃描定位 0x/0X
while (s[i] != '\0') {
if (s[i] == '0') {
++i;
if (s[i] == 'x' || s[i] == 'X') {
++i; break; // 找到前綴,跳出掃描
}
} else {
++i; // 繼續掃描
}
}
n = 0; inhex = 1;
for (; inhex; ++i) {
// ... 原轉換邏輯不變 ...
}
return n;
}
#include <stdio.h>
#define YES 1
#define NO 0
int htoi(char s[]);
int main(void) {
int c, i;
char input[10]; // 最多9有效字符 + \0
for (i = 0; i < 9 && ((c = getchar()) != EOF); ++i)
input[i] = c;
input[i] = '\0';
printf("輸入的16進制數轉換十進制數:%d\n", htoi(input));
return 0;
}
int htoi(char s[]) {
int hexdigit, i, inhex, n;
i = 0;
while (s[i] != '\0') {
if (s[i] == '0') {
++i;
if (s[i] == 'x' || s[i] == 'X') {
++i; break;
}
} else ++i;
}
n = 0; inhex = YES;
for (; inhex == YES; ++i) {
if (s[i] >= '0' && s[i] <= '9') hexdigit = s[i] - '0';
else if (s[i] >= 'a' && s[i] <= 'f') hexdigit = s[i] - 'a' + 10;
else if (s[i] >= 'A' && s[i] <= 'F') hexdigit = s[i] - 'A' + 10;
else inhex = NO;
if (inhex == YES) n = 16 * n + hexdigit;
}
return n;
}

輸入abc0x1F正確輸出31,實現了對前導無效字符的容錯處理,顯著提升函數通用性。
通過增加前導掃描邏輯,使htoi能處理含雜質字符的輸入,更貼近實際工程場景。這體現了「防禦性編程」思想:函數應盡可能兼容非標準輸入,增強魯棒性。