一、我最开始接触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;
}