c - 如何测试输入是否正常

标签 c

考虑以下简单的 C 程序。

//C test

#include<stdio.h>

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

   printf("Enter two numbers to add\n");
   scanf("%d%d",&a,&b);

   c = a + b;
   printf("Sum of entered numbers = %d\n",c);
   return 0;
}

如何检查输入的值实际上是某个合理范围内的两个整数?目前,如果您只输入“a”然后返回,您将得到输出“输入数字的总和 = 32767”。

我想避免的错误输入示例。

  1. 2 3 4(数字错误)
  2. 苹果(不是数字)
  3. 11111111111111111111111111 111111111111111111111111111111111111(数字超出范围)

或者我应该使用 fgetssscanf 还是 strtol

最佳答案

用户输入是邪恶的。解析依据:

(optional whitespace)[decimal int][whitespace][decimal int](optional whitespace)

strtol() 和 family 比 scanf() 有更好的错误处理。
Coda:最好在辅助函数中处理用户输入。分成两部分:I/O 和解析。

#include <ctype.h>
#include <errno.h>
#include <limits.h>
#include <stdio.h>
#include <stdlib.h>

// return 1 (success), -1 (EOF/IOError) or 0 (conversion failure)
int Readint(const char *prompt, int *dest, size_t n) {
  char buf[n * 21 * 2]; // big enough for `n` 64-bit int and then 2x

  fputs(prompt, stdout);  // do not use printf here to avoid UB
  fflush(stdout); // per @OP suggestion
  if (fgets(buf, sizeof buf, stdin) == NULL) {
    return -1;
  }
  const char *p = buf;

  while (n-- > 0) {
    char *endptr;
    errno = 0;
    long l = strtol(p, &endptr, 10);
    if (errno || (p == endptr) || (l < INT_MIN) || (l > INT_MAX)) {
      return 0;
    }
    *dest++ = (int) l;
    p = endptr;
  }

  // Trailing whitespace OK
  while (isspace((unsigned char) *p)) p++;
  // Still more text
  if (*p) return 0;
  return 1;
}

int main() {  // for testing
  int Result;
  do {
    int dest[2] = { -1 };
    Result = Readint("Enter two numbers to add\n", dest, 2);
    printf("%d %d %d\n", Result, dest[0], dest[1]);
  } while (Result >= 0);
  return 0;
}

关于c - 如何测试输入是否正常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20262101/

相关文章:

有人可以告诉我为什么会出现这个运行时错误吗?

C 编程 : getchar() won't accept '+' or '-' for input, 但会接受 '*' 和 '/' 吗?

c - SimpleDB HMAC 签名

c - 默认 Argv 参数类型

c - SEH 异常导致我的程序逻辑错误?

c - asmlinkage 在 Linux 代码中没有定义

c++ - 仅通过帐户名获取 Windows 用户帐户 SID

c - 如何捕获断开连接事件?

c - 有没有办法从 linux 命令行中找到关于 C 关键字的信息?

c++将dll注入(inject)cmd.exe监控命令