【问题标题】:How to stop user from inserting characters instead of integers如何阻止用户插入字符而不是整数
【发布时间】:2021-07-05 10:50:10
【问题描述】:

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

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.bDay, &user.bMonth, &user.bYear);
}

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

【问题讨论】:

  • 查看scanf的返回值。
  • 使用isalpha(user.bDay) 等是没有意义的,因为这些值应该是int 类型(以匹配%d 格式)并且要么是@ 转换的结果987654326@(如果成功)或未修改(如果不成功)。检查有效输入的一种选择是使用fgets 将整行读取为字符串,并在使用sscanf 转换值之前检查有效输入。当然有不同的方法来实现这一点。一般来说,scanf 不应该用于必须检查的用户输入,而只能用于保证具有特定格式的输入。

标签: c loops crash isalpha


【解决方案1】:

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

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

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

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

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

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

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

【讨论】:

    【解决方案2】:

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

    将用户输入的读入带有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.bDay, &user.bMonth, &user.bYear, &junk) == 3
          && user.bDay >= 1 && user.bMonth >= 1 && user.bMonth <= 12 /* ... */) {
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-08-09
      • 2012-07-12
      • 2022-12-17
      • 1970-01-01
      • 2019-09-19
      • 2021-12-12
      • 1970-01-01
      • 2015-03-02
      相关资源
      最近更新 更多