仅允许使用scanf输入数字值

3

如何确保用户只输入数字,而不是字母数字或其他字符?还需要查找哪些内容以插入有关错误输入的错误消息?

#include<stdio.h>

int main()
{
   int a, b, c;


   printf("Enter first number to add\n");
   scanf("%d",&a);

   printf("Enter second number to add\n");
   scanf("%d",&b);

   c = a + b;

   printf("Sum of entered numbers = %d\n",c);

   return 0;
}

1
如果在格式字符串为%d的情况下输入非数值类型的内容,那么scanf将会抛出一个错误。使用scanf()函数的返回值,阅读:Scanf无法第二次执行 - Grijesh Chauhan
4个回答

3

如果你真的想处理可能有敌意的用户输入,请使用一个单独的函数来获取数字。

允许:
- 前导空格: " 123"
- 尾随空格: "123 "
- 前导零: "0000000000000000000000000000000000123"
- 错误输入后可以重新扫描。
捕捉以下错误:
- 没有输入:"" - 数字后面有额外文本:"123 abc"
- 数字前面有文本:"abc 123"
- 分割数字:"123 456"
- 上溢/下溢:"12345678901234567890"
- 其它:"--123"
在无效输入时重新提示。

#include <errno.h>
#include <stdio.h>
#include <stddef.h>

int GetInteger(const char *prompt, int *i) {
  int Invalid = 0;
  int EndIndex;
  char buffer[100];
  do {
    if (Invalid)
      fputs("Invalid input, try again.\n", stdout);
    Invalid = 1;
    fputs(prompt, stdout);
    if (NULL == fgets(buffer, sizeof(buffer), stdin))
      return 1;
    errno = 0;
  } while ((1 != sscanf(buffer, "%d %n", i, &EndIndex)) || buffer[EndIndex] || errno);
  return 0;
}

int main() {
  int a, b, c;
  if (GetInteger("Enter first number to add\n", &a)) {
    ; // End of file or I/O error (rare)
  }
  if (GetInteger("Enter second number to add\n", &b)) {
    ; // End of file or I/O error (rare)
  }
  c = a + b;
  printf("Sum of entered numbers = %d\n",c);
  return 0;
}

顺便说一下,你不应该使用printf("Enter first number to add\n")。应该使用fputs()。考虑一下如果字符串中有一个%会发生什么。


@user2741667 添加了必要的 #include 文件。代码编译时没有语法错误。 - chux - Reinstate Monica

1
最好完全避免使用scanf。使用fgets获取整行,然后使用sscanf提取所需信息。检查sscanf的返回值以确保输入符合预期。

0

编辑- 我需要在while循环中添加getchar(),因为未读取的非数字项留在输入队列中会导致程序进入无限循环,此外我还为相同的事情添加了更紧凑的while循环形式,两者将具有相同的效果。

您可以检查scanf的返回值,它在与格式说明符成功匹配时返回1,在不匹配时返回0。您可以像这样为您的程序执行此操作:

#include <stdio.h>
#include <stdbool.h>
int main(void)
{ 
  int num;
  bool status;//_bool may also be used and stdbool.h won't be needed for that

  status = scanf ("%d",&num);

  if (status != 1 )
    {
      getchar();// needed to add it to eat up the unread item left in input queue.
      while (status != 1)
        {
          printf (" sorry ! incorrect input :ERROR: try again");

          status = scanf("%d", &num);

        }
    }
  /*....do something...*/
  return 0;
}

更紧凑的 while 循环形式:-

while (scanf("%d",&num) != 1)
    {
      getchar();
          printf (" sorry ! incorrect input :ERROR: try again\n");
    }

此外,您应该始终为变量使用有意义的名称,例如num1num2,而不是ab

0
请阅读scanf的手册页面。您需要检查返回值。如果能够匹配数字,则应返回1。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接