不使用atof实现C语言char字符串转double的ascii_to_float函数问题
C语言ascii_to_float函数实现方案
原有代码核心问题
sprintf使用错误:第一个参数要求是字符数组地址,直接传入未初始化的double类型变量ausgabe会直接触发内存访问异常- 校验逻辑完全颠倒:原有代码仅允许小数点存在,其余字符直接标记为-1,和需求完全相反
- 直接修改输入字符串:对入参
textzahl的赋值操作会修改主函数中原始输入的字符数组,属于非法操作 - 缺少数值转换逻辑:仅做了字符校验没有实现字符到double的转换计算
实现思路
- 输入合法性校验
- 统计字符串中小数点的数量,必须有且仅有1个,否则判定为非法
- 除小数点外的所有字符必须是0~9的数字,否则判定为非法
- 自动过滤
fgets读取输入时带入的末尾换行符
- 数值转换逻辑
- 先计算小数点左侧的整数部分:每遍历一位整数,当前值 = 当前值 *10 + (当前字符 - '0'(即ASCII 48))
- 遇到小数点后开始计算小数部分:用权重变量初始为0.1,每遍历一位小数,当前值 += (当前字符 - '0') * 权重,权重每次除以10
修正后完整代码
ascii_to_float函数实现
double ascii_to_float(char *textzahl) { int len = strlen(textzahl); int dot_count = 0; int dot_pos = -1; double ausgabe = 0.0; // 第一步:合法性校验 + 记录小数点位置 for (int i = 0; i < len; i++) { // 过滤fgets读取带入的换行符 if (textzahl[i] == '\n') { len = i; break; } if (textzahl[i] == '.') { dot_count++; dot_pos = i; // 小数点超过1个直接判定非法 if (dot_count > 1) { return -1.0; } continue; } // 非小数点字符必须是数字 if (textzahl[i] < '0' || textzahl[i] > '9') { return -1.0; } } // 没有小数点也判定非法 if (dot_count != 1) { return -1.0; } // 第二步:转换小数点左侧的整数部分 for (int i = 0; i < dot_pos; i++) { ausgabe = ausgabe * 10 + (textzahl[i] - '0'); } // 第三步:转换小数点右侧的小数部分 double weight = 0.1; for (int i = dot_pos + 1; i < len; i++) { ausgabe += (textzahl[i] - '0') * weight; weight /= 10; } return ausgabe; }
主函数无需修改,可直接配合上述函数使用。
扩展说明
- 目前实现默认输入为正小数,若需要支持负数可在校验逻辑中增加对首字符为
-的适配 - 输入数值不要超过double类型的精度上限,否则会出现精度丢失
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

