注意进制,注意小数,负数,指数。
小数跟指数比较繁琐。应该对字符串做限制,字符串只是整数字符串。否则,以下几种情况都是会报错:
1. 0x011.011,0b011.011都是错误的。
2. 0100.011实际上是十进制的100.01。
3. 指数表示造成逻辑更多了。
鉴于以上几个情况考虑,为简化,整数字符串转数字。
草草写了几行代码:
typedef enum {
ErrorNull = -1,
ErrorString = -2,
Right = 0,
} ReturnCode;
typedef enum {
RadixDec = 10,
RadixHex = 16,
RadixOct = 8,
RadixBin = 2,
} Radix;
ReturnCode processNumber(char *string, size_t len, Radix radix, int flag)
{
if (!string || len == 0)
return ErrorString;
int tmp = 0, result = 0;
switch (radix) {
case RadixDec:
for (size_t i = 0; i < len; i++) {
tmp = string[i] - '0';
if (tmp < 0 || tmp > 9)
return ErrorString;
result = result * radix + tmp;
}
break;
case RadixHex:
for (size_t i = 0; i < len; i++) {
if (string[i] <= '9' && string[i] >= '0') {
tmp = string[i] - '0';
}
else if (string[i] <= 'F' && string[i] >= 'A') {
tmp = string[i] - 'A' + 10;
}
else if (string[i] <= 'f' && string[i] >= 'a') {
tmp = string[i] - 'a' + 10;
}
else {
return ErrorString;
}
result = result *radix + tmp;
}
break;
case RadixOct:
for (size_t i = 0; i < len; i++) {
tmp = string[i] - '0';
if (tmp < 0 || tmp > 7)
return ErrorString;
result = result *radix + tmp;
}
break;
case RadixBin:
for (size_t i = 0; i < len; i++) {
tmp = string[i] - '0';
if (tmp < 0 || tmp > 1)
return ErrorString;
result = result *radix + tmp;
}
break;
default:
return ErrorString;
}
//printf("%d, 0x%x, 0%o", result, result, result);
return Right;
}
ReturnCode stringToNumber(char *string, size_t len)
{
if (!string || len == 0)
return ErrorNull;
Radix numberRadix = RadixDec;
int flag = 1;
if (string[0] == '-') { //minus number
flag = -1;
if (string[1] == '0') {
switch (string[2]) {
case 'b':
numberRadix = RadixBin;
break;
case 'x':
numberRadix = RadixHex;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
numberRadix = RadixOct;
return processNumber(string + 2, len - 2, numberRadix, flag);
break;
default:
return ErrorString;
}
return processNumber(string + 3, len - 3, numberRadix, flag);
}
else if (string[1] >= '1' && string[1] <= '9') {
numberRadix = RadixDec;
return processNumber(string + 1, len - 1, numberRadix, flag);
}
else {
return ErrorString;
}
}
else if (string[0] <= '9' && string[0] >= '0') { // positive number
if (string[0] == '0') {
switch (string[1]) {
case 'b':
numberRadix = RadixBin;
break;
case 'x':
numberRadix = RadixHex;
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
numberRadix = RadixOct;
return processNumber(string + 1, len - 1, numberRadix, flag);
break;
default:
return ErrorString;
}
return processNumber(string + 2, len - 2, numberRadix, flag);
}
else {
numberRadix = RadixDec;
return processNumber(string, len, numberRadix, flag);
}
}
return ErrorString;
}
int main(int argc, const char * argv[]) {
char string[] = "1111";
return stringToNumber(string, strlen(string));
}