如何阻止用户插入字符而不是整数

问题描述

看看这段代码,它应该以属于一个结构体的三个变量的形式获取用户的出生日期。

printf("Insert date of birth in this format: dd/mm/yyyy\n");
scanf("%d/%d/%d",&user.bDay,&user.bMonth,&user.bYear);

while(isalpha(user.bDay)==1||isalpha(user.bMonth)==1||isalpha(user.bYear)==1){
    puts("Invalid input");
    scanf("%d/%d/%d",&user.bYear);
}

如果用户输入字符怎么办?像 1q/02/199i 这样的东西?我想让程序打印一条错误消息,并简单地要求用户再次插入他的出生日期。 我尝试使用 isalpha 函数,正如您在代码中看到的那样,但它不起作用,程序崩溃并无限次打印“Invalis input”。如何让用户只插入整数?

解决方法

scanf 正在扫描输入字符串中的整数。考虑到这一点,我认为您的结构是 intuint16_t 或类似结构。

在任何情况下,用 isalpha '检查'这些整数,就好像它们是字符一样,对你没有帮助。举个小例子:如果用户写了“9”(ASCII 码为 57),scanf 会将其转换为 9。9 ASCII 不是数字,也不是字母数字字符。

此外,为了确认您有一个数字,您需要使用 isdigit 进行检查。用isalpha看不是数字,是不够的;用户可能输入了某种符号,既不是字母字符也不是数字。

但是,必须对用户输入的字符进行这些检查。不能对 scanf 填充的整型变量进行。

如果您将用户输入作为字符串读取,您可以自己解析它并进行您想要的任何验证(例如,使用 strtok 将其在斜杠处拆分,然后使用 isdigit在每个标记中的每个字符上)。

或者,您可以使用 scanf,然后检查您的三个整数,它们每个都在预期范围内(1-31 表示天,1-12 表示月等)。

或者,您可以取消格式化字符串,单独询问用户日、月和年,分别验证每个。

,

如何阻止用户插入字符而不是整数

使用 fgets() 将用户输入的读入字符串
scanf() 在错误处理良好的情况下很难使用。

char buffer[100];
if (fgets(buffer,sizeof buffer,stdin)) {

然后测试字符串的有效性:

  if (sscanf(buffer,"%d /%d /%d",&user.bDay,&user.bMonth,&user.bYear) == 3) {
    Success();
  }
  else {
    puts("Invalid input");
  }
}

根据需要添加其他测试,例如范围限制和尾随垃圾测试。

  char junk;
  if (sscanf(buffer,"%2d /%2d /%4d %c",&user.bYear,&junk) == 3
      && user.bDay >= 1 && user.bMonth >= 1 && user.bMonth <= 12 /* ... */) {