標籤:
最近開始自學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 else31 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 else15 ++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 else34 ++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 else46 inhex = NO;47 if (inhex == YES)48 n = 16 * n + hexdigit;49 }50 return n;51 }
擴充《C程式設計語言》練習2-3程式通用性