最近開始自學C語言,在看K&R的《C程序設計語言》。練習2-3要求寫一個函數,將輸入的十六進制數字字符串轉換成與之等價的整數值,配套答案沒有擴展程序的通用性,所以我就稍微改造改造。
配套的答案是這樣的(自己添加了注釋):
1 #define YES 1
2 #define NO 0
3
4 /* htoi:將十六進制數字字符串轉換成十進制數
5 * 如果發現'0x'或'0X'則跳過並設置十六進制數的起點
6 * 檢查後續字符是否是0-9,a-f或是A-F
7 * 如果是則將其轉換為整形
8 * 如果不是則停止檢查,數字結束
9 * 通過公式計算相應的十進制值並返回
10 */
11 int htoi(char s[])
12 {
13 int hexdigit,i,inhex,n;
14
15 if (s[i] == '0') {
16 ++i;
17 if (s[i] == 'x' || s[i] == 'X'){
18 ++i;
19 }
20 }
21 n = 0; /* 初始化返回變量 */
22 inhex = YES; /* 假設在合法字符中 */
23 for ( ; inhex == YES; ++i) {
24 if (s[i] >= '0' && s[i] <= '9')
25 hexdigit = s[i] - '0';
26 else if (s[i] >= 'a' && s[i] <= 'f')
27 hexdigit = s[i] - 'a' + 10;
28 else if (s[i] >= 'A' && s[i] <= 'F')
29 hexdigit = s[i] - 'A' + 10;
30 else
31 inhex = NO;
32 if (inhex == YES)
33 n = 16 * n + hexdigit;
34 }
35 return n;
36 }
該函數需要導入一個字符數組,我在 main() 函數中寫了獲取數組的代碼(假設最多獲取10個長度的字符數組,因為數組以 '\0' 結尾,因此總共最多獲取9個有效字符):
1 int c,i; 2 char input[10]; 3 4 for ( i = 0; i < 10-1 && ((c = getchar()) != EOF); ++i) 5 input[i] = c; 6 input[i] = '\0';
將得到的字符數組傳入 htoi() 函數中即可計算出轉換後的值。
但是這樣有個缺陷:字符數組開頭必須是 “0x” 或 “0X” 或 數字0-9 或 字母a-f 或 A-F,否則 htoi() 函數只返回 0。這樣就降低了程序的通用性,那麼如何才能當字符數組前頭包含無用字符時,只有檢測到 “0x” 或 “0X” 時才繼續檢測後續字符,並計算返回正確的結果?
我的做法是在 htoi() 函數中檢測是否為 “0x” 或 “0X” 的代碼上添加循環:
1 int htoi(char s[])
2 {
3 int hexdigit,i,inhex,n;
4
5 i=0;
6 while (s[i] != '\0'){
7 if (s[i] == '0') {
8 ++i;
9 if (s[i] == 'x' || s[i] == 'X'){
10 ++i;
11 break; /* 如果是“0x”或“0X”就停止循環 */
12 }
13 }
14 else
15 ++i; /* 如果不符合則循環到底,最後s[i]='\0' */
16 }
17 n = 0;
18 inhex = YES;
19 for ( ; inhex == YES; ++i) {
20 ... ...
運行結果如下:

下面把完整代碼貼出來,若有幸讓高手看見還請指點指點:
1 #include <stdio.h>
2
3 #define YES 1
4 #define NO 0
5
6 int htoi(char s[]);
7
8 int main(void)
9 {
10 int c,i;
11 char input[10];
12
13 for ( i = 0; i < 10-1 && ((c = getchar()) != EOF); ++i)
14 input[i] = c;
15 input[i] = '\0';
16 printf("輸入的16進制數轉換十進制數:%d\n",htoi(input));
17 return 0;
18 }
19
20 int htoi(char s[])
21 {
22 int hexdigit,i,inhex,n;
23
24 i=0;
25 while (s[i] != '\0'){
26 if (s[i] == '0') {
27 ++i;
28 if (s[i] == 'x' || s[i] == 'X'){
29 ++i;
30 break;
31 }
32 }
33 else
34 ++i;
35 }
36 n = 0;
37 inhex = YES;
38 for ( ; inhex == YES; ++i) {
39 if (s[i] >= '0' && s[i] <= '9')
40 hexdigit = s[i] - '0';
41 else if (s[i] >= 'a' && s[i] <= 'f')
42 hexdigit = s[i] - 'a' + 10;
43 else if (s[i] >= 'A' && s[i] <= 'F')
44 hexdigit = s[i] - 'A' + 10;
45 else
46 inhex = NO;
47 if (inhex == YES)
48 n = 16 * n + hexdigit;
49 }
50 return n;
51 }