再看C语言输入

    一、我最开始接触C时是从printf和scanf开始的。在用到scanf时,我总是小心翼翼的按照自己既定的规则来进行输入。若不小心输入错误的话程序就会得到错误的结果或者直接崩溃了,遇到这种情况也就只有从新运行程序并按照“正确”的方式,全部从新输入一次。
    针对上面出现的两种情况主要由两个原因引起的:
1、输入并不匹配函数 int fscanf(FILE *fp, char *format, ...) 或 int scanf(const char *format, ...) 中format所指定的输入格式。
2、输入数据超过而溢出而覆盖其他内存区域。
    二、下面详细介绍一下出现上面两种问题的原因,及相应的解决方法。
情况1:输入格式不匹配:
如:
int i;
scanf("%d",&i);
输入内容:c
    上述scanf函数执行的结果并没有从标准输入中读取数据放在i所在内存地址。根据K&R C 对scanf描述:"
It returns when  format is exhausted.  fscanf returns EOF  if end of file or an error occurs before any conversion; otherwise it returns the number of input items converted and assigned."
    因此scanf函数执行完会返回0。所以我们可以通过对scanf返回值的判断来判定输入格式的正确性。在下面的例子中我们通过scanf_int_decimal函数来实现对输入函数scanf执行结果的判断来确定输入格式的正确与否,函数中scanf("%*[^\n]")和scanf("%*c")用来清空因为错误输入而滞留在输入流stdin中的数据。
#include<stdio.h>
#include<string.h>
int main()
{
	void scanf_int_decimal(int *p,const char *format);
	int i;
	printf("Input value for i:\n");
	scanf_int_decimal(&i,"%d");
	return 0;
}
void scanf_int_decimal(int *p,const char *format)
{
	int n;
	while((n = scanf(format, p)) != 1)
	{
		scanf("%*[^\n]");
		scanf("%*c");
		printf("Incorrect format, Input again:\n");
	}
}
情况2:输入数据过多造成溢出:
    如:
char buf[10];
scanf("%s",buf) ;
    输入内容:aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa,即大于buf的大小。 在下面的例子中我们在read_line函数中实现了限定了上限的字符数据输入,在未达到输入上限时去除了输入的换行符'\n',在输入数据超过上限时我们只读取规定了的最大长度,并清空多余的滞留在stdin流中的数据。
#include<stdio.h>
#include<string.h>
int main()
{
	char buf[10];
	char *read_line(FILE *, char *, char *, unsigned int);
	read_line(stdin, "Input string:", buf, 10);
	return 0;
}

char *read_line(FILE *fp, char *prompt, char *buff, unsigned int n)
{
	char *p;
	printf("%s",prompt);
	fflush(stdout);
	if(p = fgets(buff, n, fp))
	{
		int last = strlen(buff) - 1;
		if(buff[last] == '\n')
			buff[last] = '\0';
		else
		{
			scanf("%*[^\n]");
			scanf("%*c");
		}
	}
	return p;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值