C用户只输入整数,从scanf返回值

时间:2015-10-22 14:01:57

标签: c return-value user-input scanf

我正在尝试获取一些用户输入,并且我想确保它们输入整数,如果它们不输入,我将只要求它们再次输入(循环直到它们正确)。

我找到了很多不同的方法来做到这一点;其他一些比较复杂。但我发现这种方法似乎有效。

但我真的不明白为什么在代码中对它进行了测试:

@echo off

set /p target=Please enter target:  

 if not defined target (
  echo ant default-target
  ant 
  pause
  goto :EOF
) else (
  echo ant %target%
  ant %target%
  pause
  goto :EOF
)

我可以理解scanf("%d%c", &num, &term) != 2 输出成功匹配和分配的项目数,但我不明白为什么如果它是一个整数则输出2。

C中的代码是:

scanf

尝试将其置于循环中:

int main(void)
{
    int num;
    char term;

    if (scanf("%d%c", &num, &term) != 2 || term != '\n')
        printf("failure\n");
    else
        printf("valid integer followed by enter key\n");
}

我尝试输入m = 3,n = 3,dis = 2,然后循环重新开始并要求我输入行数。如果我在被要求提供这个新闻f或其它东西时,它就会像在printf-statements上一样开始循环播放:)

4 个答案:

答案 0 :(得分:3)

scanf返回它转换的字段数。你有格式字符串%d%c;它有:

  1. %d - 第一个字段
  2. %c - 第二个字段
  3. 所以scanf返回2.

    如果用户输入了一个号码,例如123并按 Enter ,您的num将等于123term将为\n

    如果用户在最后输入带有垃圾的号码,例如123garbage并按 Enter ,您的num将等于123term将为g,{{1将保留在输入缓冲区中。

    在这两种情况下,arbage\n都会读取scanfint,因此会返回2.

    另一个例子:用户输入char。在这种情况下,garbage123将无法读取整数,并返回0.

    因此,您的代码会检查两种不同形式的错误输出。

答案 1 :(得分:1)

输入一个整数将与格式化程序%d匹配,并将值赋给变量num%c格式化程序将采用换行符('\ n')并将其存储在变量term中。 scanf返回2导致2个元素正确分配(numterm

如果您没有输入整数,格式化程序%d将无法正确匹配,scanf将不会返回2,从而导致失败

编辑:你的do-while循环变得疯狂导致上一次scanf中的条件错误(dis != 1 || dis !=2)。它应该是

if(scanf("%d%c", &dis, &dis_check) !=2 || dis_check != '\n' || (dis != 1 && dis !=2))

答案 2 :(得分:0)

scanf("%d%c", &num, &term) != 2 

这会检查return的{​​{1}}值。 scanf个参数的数量正确匹配。因此,如果输入return和字符,则会将其存储在vairables integernum以及term scanf returns中。

如果两个参数都没有正确匹配,

2将不会scanf return,在这种情况下,2将显示为输出。

答案 3 :(得分:0)

哎呀 - 现在看到OP想知道为什么接近失败并且不一定在寻找如何做到这一点。将此作为参考,因为它确实存在基本问题:scanf()。不要将它用于用户输入。

如果代码确实需要“获取一些用户输入,并希望确保它们输入整数”,则使用fgets()获取该行,然后处理输入。< / p>

将用户输入与扫描/解析混合在一起会导致某些用户输入无法检查,stdin中的额外用户输入或不正确等待更多输入。

// true implies success
bool Read_int(int *value) {
  char buffer[100];
  if (fgets(buffer, sizeof buffer, stdin) == NULL) return false; // EOF or error

  // Now parse the input
  char *endptr;
  errno = 0;
  long number = strtol(buffer, &endptr, 10);
  if (errno)                                return false; // long overflow
  if (number < INT_MIN || number > INT_MAX) return false; // int overflow
  if (endptr == buffer)                     return false; // No conversion
  while (isspace((unsigned char) *endptr)) endptr++;
  if (*endptr)                              return false; // non-white-space after number
  *value = (int) number;
  return true;
}