一个爱历史的程序猿

我知道这个世界很大。但只有疯狂到相信自己能改变世界的人,才能改变世界。

导航

如何确保获取的输入为整数-C语言基础

Posted on 2018-12-19 23:54  梁小满  阅读(605)  评论(0编辑  收藏  举报

 

在这里插入图片描述
这一篇探讨的是如何确保你输入的数据是一个整数。虽然标题用的是这个,但我其实真正想要探讨的内容是 “在程序调试的过程中,需要注意把输入缓存区中的上一次输入的残留信息清理干净,以免影响下一次的输入。” 但由于这个内容太过于冷门,且不迎合人们利用搜索引擎查找问题时关键字的搜索。所以不太适合用于做标题,于是便利用了文章中例子所实现的功能来作为标题。属于c语言基础篇。


本来是想要把代码改成精简版直接用来说明的,但是在精简代码的过程中,觉得这个代码精简的过程挺重要的,所以想要单独的废话一两句(建议编程小清新看一下,大佬的话感兴趣可以审阅一下也可以直接跳过)。

对于编程这件事情,同一个需求,一百个人可能有一百篇不一样的代码。虽然都可以实现功能,但有些人的代码跑起来就是比别人的代码效率高。同样效率的代码,有些人的代码对于内存的占用,就是比别人的小很多。当然,在编程这件事上面,时间和空间不可兼得(一个很简单的例子就是全局变量,全局变量是一个很方便效率很高的东西,代码编程的过程中合理的使用全局变量,可以有效的提高程序的运行效率。但同时你也要清楚,全局变量是与程序共存亡的,也就是说整个程序的运行阶段都需要分配一块内存来存储这个变量,这其实是在用空间的占用来换取时间的快速)。所以一个好的程序,往往是能在时间和空间上面找到合理平衡点的程序。

个人认为一个程序员对于程序的追求应该有三个阶段。
第一个阶段是程序代码的精简,
第二个阶段是在第一个阶段的基础上提升程序的效率。
第三个阶段是在第二个阶段的基础上压缩程序的空间。
很惭愧的说,本人现在还在第一个阶段中挣扎徘徊。


好了,步入正题,这里我用的例子功能为——从键盘接收一个整数,将其转换成其ASCIL码值所对应的字符输出(就是用序号查ASCIL码表)

想要实现这个需求的话,我们先分析一下整体思路,这是我老师教我的。虽然我挺不喜欢这个环节的,每次听老师讲思路分析都会犯困,我倒是挺喜欢直接看代码的。但有时对于一些比较复杂的问题,如果不冷静下来捋一下思路,常常又会无从下手。

在这个例子里面,我们的思路很明确,既然需要把一个输入的整数转换为ASCIL码数值,那么我们首先需要从键盘接收一个整数,这里用的是scanf()函数来接收键盘数据,然后通过返回值来判断是否读取到了需要的数据。而 scanf() 函数的返回值有两种可能,要么返回接收到的数据个数,要么返回0。

利用 scanf() 函数本身的特性,这一步只有当输入数据的第一个是整型的时候, scanf() 函数的返回值才是1,否则就会返回0。这已经可以断绝掉输入的数据不是整型的可能了。


那是不是说只要我判断一下返回值是否等于1就可结束任务呢?如果我同时输入两个整形数据呢?

当然,在这个程序里面是没有问题的,因为这个程序只要接收到了第一个整形数据后,便会退出循环,结束程序。由于程序已经死掉了,后面输入的内容便会跟着程序一起被系统释放掉。

但是如果你的程序很大很大,在这里接收了用户输入后,后面也还要接收用户的输入,这里就会出现问题了。由于你在这边连续输入了多个数据,且第一个是整形,程序运行到这里的时候,仅仅只读取了第一个整型数据,而后面的残留数据被留在了缓存区,在程序下一次读取键盘数据的时候,这些残留数据就会被错误输入到程序中,就有可能导致程序出现错误。


那么既然我们意识到了同时输入多个数据可能会造成程序的意外错误,那么在这里我们就不能简单的判断scanf的返回值是否等于1了事,在程序得到了这个数据后还要判断一下这个数据后面是否还有别的数据。判断过程在代码中体现。

最后就是处理好判断的结果就行了,如果读取正常要怎么处理,如果读取不正常又要怎么处理。


Created with Raphaël 2.2.0开始scanf()接收输入判断输入是否合法转换类型输出结束清空缓存区yesno

好了先看原版代码。

#include <stdio.h>
int main(void)
{
	int pw;//这个变量是用来接受输入的
	int i;//临时变量,存储返回值用于判断
	while(1)
	{
		i = scanf("%d", &pw);
		//这一步就是判断输入的数据是否合法,且输入的仅仅是一个整数
		if(i == 1 && getchar() == '\n')
			break;
		else
		{
			// 温馨提示一下
			if(i == 1)
				printf("请仅输入一个整数!\n");
			else
				printf("你输入的不是整数,请再来一遍!\n");

			//这一步就是将缓存区中的非法格式数据拿掉的一步了
			while(1)//清空缓存区
			{
				char c = getchar();
				if(c == '\n')
					break;
			}
		}
	}
	printf("你输入的数值转为字符为:%c\n", (char)pw);
	return 0;
}

以下是精简版的代码。

#include <stdio.h>
int main(void)
{
	int pw;//这个变量是用来接受输入的
	//这一步就是判断输入的数据是否合法,且输入的仅仅是一个整数
	while(!(scanf("%d", &pw) && getchar() == '\n'))
	{
		while(getchar() != '\n');//清空缓存区
		printf("你输入的数据有误,请再输一遍!\n");//温馨提醒一下
	}
	printf("你输入的数值转为字符为:%c\n", (char)pw);
	return 0;
}

由于是第一篇博客还不太擅长组织文章的结构和对于语言的表达,原谅我把如此简单的问题复杂的扯了这么一大篇。

原博客始发于CSDN,在如今博客界的转载抄袭泛滥的环境下,原创不易,点个赞再走呗。以下是博客首页的链接。


零BUG是原则性问题。