标签:
atof函数,用于将字符串参数转化为浮点型
/*
系统:linux
自实现atof函数,主函数用于参数合法化的判断,若合法则调用子函数,否则退出
此程序包含两种算法的atof实现,均有效
*/
#include <stdio.h>
#include <string.h>
float str_to_float(char *str);
float str_to_float1(char *str);
int main(int argc, char* argv[])
{
/*
i 用于字符串的遍历
n 用于记录字符串的长度
flag_point 用于标记小数点是否已出现 默认0 出现小数点后置为1
flag_return 拥有标记字符串是否非法 默认为0 非法后置为1
result 用于存储未带+/-的结果
str 指向待转换字符串
*/
int i, n, flag_point, flag_return;
float result;
char *str;
if (argc == 1) {
fprintf(stderr, "usage: %s string\n", argv[0]);
return 1;
}
flag_point = 0;
flag_return = 0;
n = strlen(argv[1]);
str = argv[1];
result = 0.0;
for (i = 0;i < n;i++) {
//判断字符串中是否存在+/-,若在首位置则有效,否则则非法
if (str[i] == ‘+‘ || str[i] == ‘-‘) {
if (i == 0)
continue;
else {
flag_return = 1;
break;
}
}
//判断小数点最多只能出现一次,否则则非法
if (str[i] == ‘.‘) {
if (flag_point == 0)
if (i == 0) {
flag_return = 1;
break;
} else {
flag_point = 1;
continue;
}
else {
flag_return = 1;
break;
}
}
//其余字符必在0-9范围内 否则非法
if (str[i] >= ‘0‘ && str[i] <= ‘9‘)
continue;
else {
flag_return = 1;
break;
}
}
if (flag_return == 0) {
result = str_to_float(argv[1]);
printf("The %s transform float is %f\n", argv[1], result);
} else
printf("The %s string is illegal\n", argv[1]);
return 0;
}
/*
算法1
从左向右遍历字符串(由高位向低位)
例:
整数部分采取 123 = (((1*10)+2)*10)+3方法
小数部分采取0.123 = 1/10 + 2/100 + 3/1000方法
最后将整数与小数部分相加
*/
float str_to_float(char *str)
{
/*
m 保存结果的小数部分
k 保存结果的整数部分
o 保存每一位的小数部分
flag 保存正负号
flag_point 标准小数点已出现,更改转换方式
p 保存当前在小数点后位数对应的值,如第一位 p 10 第二位 p 100
*/
float m, o;
int n, i, flag, flag_point, k, p;
n = strlen(str);
flag = 1;
flag_point = 1;
k = 0;
m = 0;
o = 0;
for (i = 0;i < n;i++) {
if (i == 0 && (str[i] == ‘+‘ || str[i] == ‘-‘)) {
if (str[i] == ‘-‘)
flag = -1;
continue;
}
if (str[i] == ‘.‘) {
flag_point = 0;
p = 1;
continue;
}
if (flag_point){
k = k*10 + (str[i] - ‘0‘);
}
else {
p *= 10;
o = str[i] - ‘0‘;
m += o/p;
}
}
return flag*(k+m);
}
/*
方法2
从右向左遍历字符串(由低位向高位)
例:
12.34 先得到1234 且记录小数点位置
再用 1234/100 = 12.34
*/
float str_to_float1(char *str)
{
/*
flag 用于标记小数点位置
flag1 用于标记字符串的正负
result拥有存储结果
p 用于保存当前以访问多少位
q 用于保存共有几位小数
*/
int i, n, p, flag, q, flag1;
float result;
n = strlen(str);
result = 0;
p = 1;
q = 1;
flag = 0;
flag1 = 1;
for (i = n- 1;i >= 0;i--) {
//用于跳过最右端多余的0
if (i == (n -1))
while (str[i] == ‘0‘)
i--;
if (str[i] == ‘.‘) {
flag = 1;
continue;
}
if (flag == 0)
q *= 10;
if (i == 0 && (str[i] == ‘+‘ || str[i] == ‘-‘)) {
if (str[i] == ‘-‘)
flag1 = -1;
continue;
}
result += p*(str[i] -‘0‘);
p *= 10;
}
return flag1*result/q;
}
总结:
看似小的功能,实现起来颇飞周折,勤加练习
1、变量在申请后,使用前一定要赋初始值
2、float类型变量在赋值过程中存在精度损失
3、边界的判断问题
标签:
原文地址:http://my.oschina.net/u/2313065/blog/485333