自己实现atof

来源:互联网 发布:云宫迅音评价知乎 编辑:程序博客网 时间:2024/06/06 12:50

基本想法:

例:123.456E1234,其中小数点前面算整数部分,小数点到E是小数部分,E后面的是有效数部分。

#include <iostream>#include <string>#include <fstream>#include <cctype>using std::string;using std::ifstream;#define INTEGER 0#define FRACTION 1#define SIGNIF 2float fractorial(int value){float num = 1;if(value < 0)for(int i = -value; i > 0; --i)num *= 0.1;else if(value > 0)for(int i = value; i > 0; --i)num *= 10;return num;}float atof(const string &expr){string::const_iterator begin = expr.begin();string::const_iterator end = expr.end();float value = 0;float integer = 0;float fraction = 0;int signif = 0;float minus = 1;int flag = INTEGER;int sign1 = 1;int sign2 = 1;for(; begin != end; ++begin){while(*begin == ' ') continue;   //delete the lead spaceif(*begin == '-')if(flag == INTEGER)sign1 = -1;else if(flag == SIGNIF)sign2 = -1;if(*begin == '-' || *begin == '+' )continue;if(isdigit(*begin)){if(INTEGER == flag){  //caculate the interger integer = integer * 10 + *begin - '0';}else if(FRACTION == flag){                    //caculate the float fraction = fraction * 10 + *begin - '0';minus *= 0.1;}else{     //caculate the effective numbersignif = signif * 10 + *begin - '0';}}else if(*begin == '.'){flag = FRACTION;}else if(*begin == 'e' || *begin == 'E'){flag = SIGNIF;}}return sign1*(integer + fraction * minus) *fractorial(sign2 * signif); }int main(){ifstream ifs("data.txt");string expr;while(std::getline(ifs, expr)){std::cout << atof(expr) << std::endl;}        ifs.close();        return 0;}

测试文件data.txt:
+12.23                                                                                                                               
0.34e3
.4E3
-1.345E-3
345
+23e-5
测试结果:

[root@localhost atof]# ./atof
12.23
340
400
-0.001345
345
0.00023

基本测试能过,其中有一些异常情况没考虑(空串,非数字字符)。

0 0
原创粉丝点击