TAKEAWAY 8.23 숫자로 인코딩된 문자를 해석하는 방식은 실행 환경에 정의된 문자 집합에 따라 다르다.
이런 코드를 사용하면 이식성이 나빠지므로 사용하지 않는 것이 좋다.
다음 코드에 나오는 hexatridecimal 함수는 방금 설명한 기능을 이용하여 문자 및 숫자에 대해 베이스 36(base 36) 숫자 값을 제공한다. 이 값은 16진수 상수와 비슷하지만 나머지 문자도 베이스 36 값이라는 점이 다르다. Exs 8, Exs 9, Exs 10
strtoul.c
8 /* 소문자가 연달아 나온다고 가정한다. */
9 static_assert('z'-'a' == 25,
10 "alphabetic characters not contiguous");
11 #include <ctype.h>
12 /* 문자와 숫자를 부호 없는 정수로 변환한다. */
13 /* '0' ... '9' => 0 .. 9u */
14 /* 'A' ... 'Z' => 10 .. 35u */
15 /* 'a' ... 'z' => 10 .. 35u */
16 /* 나머지 값 => Greater */
17 unsigned hexatridecimal(int a) {
18 if (isdigit(a)) {
19 /* 반드시 실행된다.
20 십진수 숫자가 연달아 나오고
21 isdigit은 로케일에 영향을 받지 않는다. */
22 return a - '0';
23 } else {
24 /* 소문자가 아니면 변경하지 않고 그대로 둔다. */
25 a = toupper(a);
26 /* 라틴 대문자가 아니면 36보다 크거나 같은 값을 리턴한다. */
27 return (isupper(a)) ? 10 + (a - 'A') : -1;
28 }
29 }
Exs 8 hexatridecimal의 두 번째 return에서는 a와 'A' 사이의 관계에 대해 뭔가를 가정하고 있다. 가정한 사실은 무엇일까?
Exs 9 이 가정을 충족하지 못할 경우 발생할 수 있는 오류 상황을 설명해 보자.
Exs 10 앞의 버그를 수정해 보자. 다시 말해 a와 'A' 사이의 관계에 대한 어떠한 가정을 하지 않도록 코드를 수정해 보자.