实例28:从键盘读入实数

题目要求:

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

思路:

其实一开始我是懵逼的(╯︵╰),输入实数的话用scanf不就可以了吗?为啥还要转换呢?在经过一些思考后,发现要理解这道题需要了解以下一些知识点:

1.标准输入\输出流

2.getchar()等相关函数的使用

知识点:(内容摘自于《C语言大学教程》中文第六版)

此题需要从标准输入流(standard input stream)输入数据(虽然输入\输出流是在一起的,但本题更关注的是输入),并将数据输出到标准输出流。

流:

所有的输入/输出都是基于流(stream)实现的,所谓流就是字节的序列。在输入操作中,字节从一个外部设备流向主存;在输出操作中,字节从流主存流向一个外部设备。

当程序开始执行时,有三个流被自动地连接到程序上:

标准输入流:连接到键盘上(操作系统可以将其重定向到其他设备上)

标准输出流:连接到显示器上(操作系统可以将其重定向到其他设备上)

标准错误流:

对于我这种初学者来说,在C语言中说的输入数据首先想到的是scanf函数:

scanf函数具有如下格式化输入功能:

1. 输入任意一种类型的数据,也就是说可以用scanf函数直接读取输入的实数,但是需要指定格式(即,明确的高速编译器你输入的是实数)

2. 从一个输入流中指定的字符

3. 忽略一个输入流中指定的字符

调用scanf函数的格式:

scanf(格式控制字符串,其余实参);

格式控制字符串:描述了输入数据的格式

其余实参:指向存储输入数据的目标变量的指针

getchar函数:

可以参考链接:https://blog.csdn.net/nopoppy/article/details/51906337

在此程序中就是把输入当做字符进行处理将其转换成实数。

原书实例代码如下所示:

 #define ERR 5
#define OK 6
#include <stdio.h> int status;
double result,sig,scale; int sign(int c)/*处理数的符号函数*/
{
if(c=='-')/*若为负号,置负数标记*/
sig=-sig;
} int integer(int c)/*转换整数部分,转换一位整数位*/
{
result=result*10.0+c-'';
} int decimal(int c)/*转换小数部分,转换一位小数位*/
{
result+=(c-'')*scale;
scale/=10.0;
}
/*状态表*/
int statbl[ ][]={{ ,,,ERR},/**/
{ERR,,,ERR},/**/
{OK,,,OK},/**/
{ERR,,ERR,ERR},/**/
{OK,,OK,OK}};/**/
//状态变量为1表示已遇数的符号字符
//状态变量为2表示正在转换实数的整数部分
//状态变量为3表示在未遇到数字字符之前先遇到小数点,必须要有小数部分
//状态变量为4表示在转换整数部分之后遇到小数点,这种情况可以没有小数部分。 /*转换函数表*/
int(*funtbl[ ][])( )={{sign,integer,NULL,NULL},
{NULL,integer,NULL,NULL},
{NULL,integer,NULL,NULL},
{NULL,decimal,NULL,NULL},
{NULL,decimal,NULL,NULL}}; int readreal(double *dp)
{
int c,ckind;
sig=1.0;
result=0.0;
scale=0.1; while((c=getchar( ))==' '||c=='\n'||c=='\t');/*跳过前导空白符*/
status=;/*置初始状态*/
for(;;)
{
/*分类当前字符*/
if(c=='+'||c=='-') ckind=;/*数的符号字符*/
else if(c>=''&&c<='') ckind=;/*数字符*/
else if(c=='.') ckind=;/*小数点*/
else ckind=;/* 其它字符 */ 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 ;
}
return -; /* 出错返回 */
}
main()
{
double x;
//clrscr();
printf("\nPlease input real numbers (use nonreal char to end input):\n");
while(readreal(&x)==)
printf("The real number you input is: %f\n",x);
printf("\nYou have inputted nonreal char.\n Press any key to quit...\n");
getch();
}

一些测试结果如下所示:

结论:

虽然程序还是可以基本看懂的,但是自己独立写的话,根本写不出这种程度的代码。..(。•ˇ‸ˇ•。)…

C语言实例解析精粹学习笔记——28的更多相关文章

  1. C语言实例解析精粹学习笔记——18

    <C语言实例解析精粹>中编译环境采用的是Turbo C 2.0.但是这个编译器年代久远,较新的编译器对书中的某些例子支持不好,在学习的时候同时做一些笔记. 实例18:将一个无符号整数转换为 ...

  2. C语言实例解析精粹学习笔记——35(报数游戏)

    实例35: 设由n个人站成一圈,分别被编号1,2,3,4,……,n.第一个人从1开始报数,每报数位m的人被从圈中推测,其后的人再次从1开始报数,重复上述过程,直至所有人都从圈中退出. 实例解析: 用链 ...

  3. C语言实例解析精粹学习笔记——42(插入排序)

    实例说明: 将一个整数数组按从小到大的顺序进行排序.(主要学习基本的插入排序和改进的冒泡排序的算法和应用) 思路1: 从第一个数据开始,分别比较其后的数据,若比它小,则将这两个数的位置交换:从第一个数 ...

  4. C语言实例解析精粹学习笔记——36(模拟社会关系)

    实例: 设计一个模拟社会关系的数据结构,每个人的信息用结构表示,包含名字.性别和指向父亲.母亲.配偶.子女的指针(只限两个子女).要求编写以下函数: (1)增加一个新人的函数 (2)建立人与人之间关系 ...

  5. C语言实例解析精粹学习笔记——32

    实例32: 编制一个包含姓名.地址.邮编和电话的通讯录输入和输出函数. 思路解析: 1.用结构体来完成姓名.地址.邮编和电话的组合. 2.结构体指针的使用. 3.malloc的使用 4.scanf函数 ...

  6. C语言实例解析精粹学习笔记——31

    实例31: 判断字符串是否是回文 思路解析: 引入两个指针变量(head和tail),开始时,两指针分别指向字符串的首末字符,当两指针所指字符相等时,两指针分别向后和向前移动一个字符位置,并继续比较, ...

  7. C语言实例解析精粹学习笔记——30

    实例30: 用已知字符串s中的字符,生成由其中n个字符组成的所有字符排列.设n小于字符串s的字符个数,其中s中的字符在每个排列中最多出现一次.例如,对于s[]="abc",n=2, ...

  8. C语言实例解析精粹学习笔记——19

    实例19:判断正整数n的d进制表示形式是否是回文数(顺着看和倒着看相同的数). 主要思路: 一种方法:将正整数n数转换成d进制的数,逐个比较首尾对应数字,判断是否为回文数. 另一种方法:将正整数n数转 ...

  9. C语言实例解析精粹学习笔记——43(希尔排序)

    实例说明: 用希尔排序方法对数组进行排序.由于书中更关注的实例,对于原理来说有一定的解释,但是对于第一次接触的人来说可能略微有些简略.自己在草稿纸上画了好久,后来发现网上有好多很漂亮的原理图. 下面将 ...

随机推荐

  1. dom父节点

  2. HTTP的GET和POST格式解析

    本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/yc0188/archive/2009/10/29/4741871.aspx HTTP报文是面向文本的,报文中的每一个字 ...

  3. BZOJ4245: [ONTAK2015]OR-XOR(前缀和)

    题意 题目链接 Sol 又是一道非常interesting的题目 很显然要按位考虑 因为最终答案是xor之后or,所以分开之后之后这样位上1的数量是一定是偶数,否则直接加到答案里面 同时,这里面有些部 ...

  4. Cloud Computing

    More numbers, More power. We waste much more every day. Everything can be connectible through specia ...

  5. http头部如何对缓存的控制

    文章自于我的个人博客 使用缓存的目的就是在于减少计算,IO,网络等时间,可以快速的返回,特别是流量比较大的时候,可以节约很多服务器带宽和压力. 一个请求从缓存的方面来说,有三个过程. 本地检查缓存是否 ...

  6. SAP成都研究院飞机哥: SAP C4C中国本地化之微信聊天机器人的集成

    今天的文章仍然来自Jerry的老同事,SAP成都研究院的张航(Zhang Harry).关于他的背景介绍,请参考张航之前的文章:SAP成都研究院飞机哥:程序猿和飞机的不解之缘.下面是他的正文. 大家好 ...

  7. IOS 发布程序(打包上传)

    • 发布程序的主要步骤 登录开发者主页 生成cer证书:cer是一个跟电脑相关联的证书文件,让电脑具备发布程序的功能 添加App ID:发布哪些app? 生成MobileProvision文件:生成一 ...

  8. POJ-2456 Aggressive cows---最大化最小值(也就是求最大值)

    题目链接: https://vjudge.net/problem/POJ-2456 题目大意: 有n个牛栏,选m个放进牛,相当于一条线段上有 n 个点,选取 m 个点, 使得相邻点之间的最小距离值最大 ...

  9. mmap内存映射

    http://blog.csdn.net/kongdefei5000/article/details/70183119 内存映射是个很有用,也很有意思的思想.我们都知道操作系统分为用户态和内核态,用户 ...

  10. 2018.9.7 ArrayList

    ArrayList简介 ArrayList核心源码 ArrayList源码分析 System.arraycopy()和Arrays.copyOf()方法 两者联系与区别 ArrayList核心扩容技术 ...