实例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. intellijidea课程 intellijidea神器使用技巧1-5 idea界面介绍

    菜单栏介绍: file:文件操作edit:文本操作view:视图操作navigate:跳转code:源码文件analyze:项目依赖关系分析refactor:代码重构快捷操作,如:抽取函数build: ...

  2. (转)两张Firefox OS 系统截图

    锁屏图 锁屏就是一个向上的小火箭. 桌面 桌面又是另一种风格. 注意 以上为Android系统下运行b2g. 原文地址,TZone

  3. IIS7 配置SSL 绑定主机头

    IIS7下面默认HTTPS绑定是无法指定主机头的,我们可以通过手工修改IIS配置来实现主机头绑定. 首先停止IIS服务. 然后打开C:/Windows/system32/inetsrv/config/ ...

  4. sharepoint2010的几个类型字段赋值和取值的方法

    1.日期类型查询,需要转换,方法如下: //转换时间 string startdate = SPUtility.CreateISO8601DateTimeFromSystemDateTime(Date ...

  5. SharePoint 和 Windows Phone 7 开发人员培训资源

     该工具包包括单位数目: Windows Phone 7 发展简介 在本单元中,您将了解真实的消费信息存储在 SharePoint 中与你用 Visual Studio 写 Windows Phone ...

  6. Centos 7.0_64bit 下安装 Zabbix server 3.0服务器的安装

    一.关闭selinux   修改配置文件/ etc / selinux / config,将SELINU置为禁用(disabled)   vim /etc/selinux/config  # This ...

  7. MySQL入门很简单: 1 数据库概述

    1. 数据库概述 1.1 数据存储方式: 1)人工管理阶段 2)文件系统阶段: 文件系统通过文件的存储路径和文件名称访问文件中的数据 3)数据库系统阶段:Oracle, SQL Server, MyS ...

  8. php session小节

    1.为什么要用session? 在人们访问网站的时候,有很多个网页,由于http自身的特点,用户每执行一个脚本都需要和web服务器重新建立连接.由于他们之间是无状态的,这次的连接无法得到上次连接的状态 ...

  9. DOM(十四):代理检测和事件处理(跨浏览器)

    一.检测 用于用户代理检测,检测范围包括浏览器引擎.平台.Windows.移动设备和游戏系统等 /* *用户代理检测脚本,检测范围包括浏览器引擎.平台.Windows.移动设备和游戏系统 */ var ...

  10. CFG的定义

    最近在CMU上NLP,好吧 对于见了很多年的CFG(Context-Free Grammar)发现又搞不懂是什么了 教材上写的是: mathematical system for modeling c ...