博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从键盘读入实数
阅读量:6388 次
发布时间:2019-06-23

本文共 2831 字,大约阅读时间需要 9 分钟。

版权声明:您好,转载请留下本人博客的地址,谢谢 https://blog.csdn.net/hongbochen1223/article/details/45805259

编制一个从键盘读入实数的函数readreal(double *rp)。函数将读入的实数字符列换成实数后,利用指针参数rp,将实数存于指针所指向的变量*rp

解析:

函数在返回之前,将最后读入的结束实数字符列的字符返还给系统,以便随后读字符时能再次读入该字符。函数若能正常读入实数,函数返回整数1,如果函数在读入过程中,未遇到数字符之前,遇到不能构成数字的情况,函数返回-1,表示为读到实数。

在输入实数时,在实数之前可以有一个数不定的空白类字符,组成实数的字符列有数的符号字符,实数的整数部分,小数点和实数的小数部分,其中,某些部分可以缺省。设实数字符列有以下几种可能形式:

数符 整数部分

数符 整数部分
数符 整数部分.小数部分
数符 .小数部分

其中数符或为空,或为’+’,或为’-‘,分别代表不带符号,带正号,带负号。整数部分和小数部分至少要有一个数字符组成。

上述实数形式说明,在实数转换过程中,同一字符在不同情况下会有不同的意义。为标记当前实数转换的不同情况,程序引入状态变量,有状态变量的不同值代表当前实数转换过程中的不同情况。

共有以下多种不同的情况:正准备开始转换,转换了数的符号字符,正在转换实数的整数部分,正在转换实数的小数部分,发现输入错误,转换正常结束。设状态变量为0表示正准备开始转换,还未遇到任何与实数有关的字符;1表示已经遇到数的符号字符;2表示正在转换实数的整数部分,3表示在未遇到数字字符之前先遇到小数点;4表示在转换整数部分之后遇到小数点;5表示转换发现错误,6表示转换正常结束。

读函数另外有两张表,一张是转换函数表,一张是状态表。函数反复读入字符,将字符分类,根据当前状态和当前字符类调用对应转换函数。

下面是程序的实现部分:

#include 
#define ERR 5#define OK 6int status;double result,sig,scale;/* * 处理数的符号函数 */int sign(int c){ if(c = '-') /* 若为负号,取负 */ sig=-sig;}/** * @brief integer 转换整数部分 * @param c 要被转换的整数位 * @return 返回成功与否 */int integer(int c){ result = result * 10.0 + c - '0';}/** * @brief decimal 转换小数部分 * @param c 要被转换的小数位 * @return 返回成功与否 */int decimal(int c){ result += (c -'0') * scale; scale /= 10;}/* 状态表 *//* * 0 - 正准备开始转换,还未遇到任何与实数有关的字符 * 1 - 已遇数的符号字符 * 2 - 正在转换实数的整数部分 * 3 - 在未遇数字字符之前先遇到小数点 * 4 - 在转换整数部分之后先遇到小数点 * 5 - 表示转换发现错误 * 6 - 转换正常结束 */int statbl[][4]={ {
1,2,3,ERR}, {ERR,2,3,ERR}, {OK,2,4,OK}, {ERR,4,ERR,ERR}, {OK,4,OK,OK}};/* 转换函数表 */int (*funtbl[][4])() = { {sign,integer,NULL,NULL}, {NULL,integer,NULL,NULL}, {NULL,integer,NULL,NULL}, {NULL,decimal,NULL,NULL}, {NULL,decimal,NULL,NULL}};/** * @brief readreal 用于对输入的字符串转换成浮点数 * @param dp 转换后的浮点数 * @return 返回是否转换成功 */int readreal(double *dp){ int c,ckind; sig = 1.0; result = 0.0; scale = 0.1; while((c=getchar()) == ' ' || c == '\n' || c == '\t'); //跳过这些字符 status = 0; //重置初始状态 for(;;){ /* 分类当前字符 */ if(c == '+' || c== '-') ckind = 0; /* 数的符号字符 */ else if(c >= '0' && c <= '9') ckind = 1; /* 数字符 */ else if(c == '.') ckind = 2; /* 小数点 */ else ckind = 3; /* 其他字符 */ if(funtbl[status][ckind]){ (*funtbl[status][ckind])(c); /* 执行相应的转换函数 */ } status = statbl[status][ckind]; /* 设置新的状态 */ if(status == ERR || status == OK) break; /*结束,出错或成功 */ c=getchar(); } ungetc(c,stdin); /* 归还数的结束符*/ if(status == OK){ *dp = result * sig; return 1; } return -1;}int main(){ double x; printf("Please input real numbers:\n"); while(readreal(&x) == 1) printf("The real number is : %f\n",x); return 0;}

下面是我的程序的运行结果:

这里写图片描述

这个程序刚开始的时候,我的思路是,从第1个元素开始遍历,遍历过程中,在遇到”.”之前,类似于上面integer()函数的实现方式,当遇到点之后,就类似于上面decimal()函数的实现方式,但是看了作者的源码之后,发现需要学习一个做着的思路,思路敏捷,代码整洁,需要好好学习。

你可能感兴趣的文章
图的单源最短路径,Floyd算法(数据结构c++)
查看>>
MSSQL Sql加密函数 hashbytes 用法简介
查看>>
NutzCodeInsight 2.0.7 发布,为 nutz-sqltpl 提供友好的 ide 支持
查看>>
一个思维习惯,让你成为架构师
查看>>
DNS子域授权
查看>>
MyBatis批量插入
查看>>
MySQL 数据类型
查看>>
进制转换算法
查看>>
RMAN-06214问题处理
查看>>
mysql半同步复制问题排查
查看>>
WIN2008系统的IIS7.0配置REWRITE伪静态环境
查看>>
36.Linux软件管理--YUM工具
查看>>
HACMP 认证学习系列,第 2 部分-1:计划与设计
查看>>
flex-10 flexfabric区别
查看>>
python 通过paramiko模块批量执行ssh命令
查看>>
Which SQL Operation May use Temp space?
查看>>
Linux下Redis-3.0.7版本的安装以及Redis主备的部署(二)
查看>>
使用OPATCH_DEBUG环境变量调试Opatch工具
查看>>
深度揭秘Windows 7
查看>>
sed 每次只替换一行
查看>>