在minix2.0源代码中,有将字符串类型转换为int、long、double类型的函数实现,相关的实现函数分别在atoi.c、atol.c、atof.c文件中,我们来逐一学习其中的源码:
1、int atoi(register const char *nptr) :将字符串类型转换为int类型
int atoi(register const char *nptr){ int total = 0; int minus = 0; //记录正负的变量(0:'+',1:'-') while (isspace(*nptr)) nptr++; //滤去前导空格字符 if (*nptr == '+') nptr++; else if (*nptr == '-') { minus = 1; nptr++; } while (isdigit(*nptr)) { total *= 10; total += (*nptr++ - '0'); } return minus ? -total : total;}
2、long atol(register const char *nptr) :将字符串类型转换为long类型,与atoi极为类似
1 long atol(register const char *nptr) 2 { 3 long total = 0; 4 int minus = 0; 5 6 while (isspace(*nptr)) nptr++; 7 if (*nptr == '+') nptr++; 8 else if (*nptr == '-') { 9 minus = 1;10 nptr++;11 }12 while (isdigit(*nptr)) {13 total *= 10;14 total += (*nptr++ - '0');15 }16 return minus ? -total : total;17 }
3、double atof(const char *nptr):将字符串类型转换为double类型
1 double atof(const char *nptr) 2 { 3 double d; 4 int e = errno; 5 6 d = strtod(nptr, (char **) NULL); 7 8 //strtod: stdlib.h中定义的库函数,将字符串转换为double型 9 //double strtod(const char * restrict nptr, char ** restrict endptr); 10 errno = e;11 return d;12 }
PS:在《C程序设计语言》中Ritchie提供了一种atof的实现:
1 double atof(char *s) 2 { 3 double val, power; 4 int sign, i; 5 6 for (i = 0; isspace(s[i]); i++) 7 ; 8 sign = (s[i] == '-') ? -1 : 1; 9 if (s[i] == '+' || s[i] == '-')10 i++;11 for (val = 0.0; isdigit(s[i]); i++)12 val = 10.0 * val + (s[i] - '0');13 if (s[i] == '.')14 i++;15 for (power = 1.0; isdigit(s[i]); i++) {16 val = 10.0 * val + (s[i] - '0');17 power *= 10.0;18 }19 return sign * val / power;20 }
后面的练习4-2,要求我们对atof函数进行扩展,使它能够处理形如123.45e-6这样的科学表示法
1 #include2 3 double atof(char *s) 4 { 5 double val, power, temp, exp; 6 char flag; 7 int sign, i; 8 9 for (i = 0; isspace(s[i]); i++)10 ;11 sign = (s[i] == '-') ? -1 : 1;12 if (s[i] == '+' || s[i] == '-')13 i++;14 for (val = 0.0; isdigit(s[i]); i++)15 val = 10.0 * val + (s[i] - '0');16 if (s[i] == '.')17 i++;18 for (power = 1.0; isdigit(s[i]); i++) {19 val = 10.0 * val + (s[i] - '0');20 power *= 10.0;21 }22 temp = sign * val / power;23 if (s[i] == 'e' || s[i] == 'E')24 i++;25 flag = s[i];26 if (flag == '-' || flag == '+')27 i++;28 for (exp = 0; isdigit(s[i]) && s[i] !='\0'; i++) {29 exp = 10.0 * exp + (s[i] - '0');30 }31 if (flag == '+') {32 while(exp--) temp *= 10;33 } else {34 while(exp--) temp /= 10;35 }36 return temp;37 }38 39 int main()40 {41 char a[] = " -2309.12E-15";42 printf("%e\n",atof(a));43 return 0;44 45 }