这一阵子真忙~年关将至,人也累死!
前面已经说过,将字符串转换为数字其实就是做的字符串解析的工作,atoi也不例外。就是利用strtol函数来实现,若转换数字超过最大范围(LONG_MAX—LONG_MIN)则返回错误。原理如下:
1.实现
1: inline int tAtoi(const tChar *pStr)
2: {
3: return tStrtol(pStr, NULL, 10);
4: }
5:
6: inline long tStrtol(const tChar *pStr, tChar **pEndPtr, int nBase)
7: {
8: /*
9: Skip white space and pick up leading +/- sign if any.
10: If nBase is 0, allow 0x for hex and 0 for octal, else assume decimal
11: If nBase if already 16, allow 0x
12: */
13:
14: const tChar *pStrTmp = pStr;
15: int c = 0;
16:
17:
18: do
19: {
20: c = *pStrTmp++; /* skip whitespace */
21: } while (tIsspace(c));
22:
23: int nNegative = 0; /* remember minus sign */
24: if( c == _T('-') )
25: {
26: nNegative = 1;
27: c = *pStrTmp++;
28: }
29: else if( c == _T('+') )
30: {
31: c = *pStrTmp++; /* skip sign */
32: }
33:
34: if( nBase < 0 || nBase == 1 || nBase > 36)
35: {
36: /* bad base! */
37: if( pEndPtr )
38: /* store beginning of string in endptr */
39: *pEndPtr = const_cast(reinterpret_cast<const tChar *>(pStr));
40: return 0L; /* return 0 */
41: }
42:
43: // 判断当前是否转换为16进制
44: if( (nBase == 0 || nBase == 16) &&
45: (c == _T('0')) &&
46: (*pStrTmp == _T('x') || *pStrTmp == _T('X')) )
47: {
48: c = pStrTmp[1];
49: pStrTmp += 2;
50: nBase = 16;
51: }
52: // 是否转换为8进制
53: if( nBase == 0 )
54: nBase = (c == _T('0') ? 8 : 10);
55:
56:
57: /* if our number exceeds this, we will overflow on multiply */
58: unsigned long ulCutOff = 0;
59: int nCutLim = 0;
60:
61: ulCutOff = nNegative ? -(unsigned long)(LONG_MIN) : LONG_MAX;
62: nCutLim = ulCutOff % static_cast<unsigned long>(nBase);
63: ulCutOff /= static_cast<unsigned long>(nBase);
64:
65:
66: unsigned long acc =0;
67: int any = 0;
68: for(acc = 0, any = 0; ; c = *pStrTmp++)
69: {
70: /* convert c to value */
71: if( tIsdigit(c) )
72: c -= _T('0');
73: else if( tIsalpha(c) )
74: c -= tIsupper(c) ? _T('A') - 10 : _T('a') - 10;
75: else
76: break; /* exit loop if bad digit found */
77:
78: if( c >= nBase )
79: break;
80:
81: /* we now need to compute number = number * base + digval,
82: but we need to know if overflow occured. This requires
83: a tricky pre-check.
84: */
85: if( any < 0 || acc > ulCutOff || acc == ulCutOff && c > nCutLim )
86: any = -1;
87: else
88: {
89: any = 1;
90: acc *= nBase;
91: acc += c;
92: }
93: }
94:
95: if( any < 0 )
96: {
97: /* we would have overflowed */
98: acc = nNegative ? LONG_MIN : LONG_MAX;
99: //throw std::overflow_error("LONG_MIN or LONG MAX");
100: }
101: /* negate result if there was a neg sign */
102: else if( nNegative )
103: acc = -acc;
104:
105: if( pEndPtr != 0 )
106: *pEndPtr = const_cast(reinterpret_cast<const tChar *>(any ? pStrTmp - 1: pStr));
107:
108: return acc;
109: }
测试代码为
1: tChar *str = NULL;
2: int value = 0;
3:
4: // An example of the atoi function.
5: str = _T(" -2309 ");
6: value = CY_CRT::tAtoi( str );
7: wcout << value << endl;
8:
9: // Another example of the atoi function.
10: str = _T("31412764");
11: value = CY_CRT::tAtoi( str );
12: wcout << value << endl;
怎么CSDN的Blog发图片一直被审核呢?莫非被最近的网络整风给怔住了?