使用 scanf 过滤掉负数

Filtering out negative numbers using scanf

我的目标是只扫描一些正数 a,如果输入负数,函数应该打印错误:

if ( scanf("%u %lf", &a, &b) != 2 ) {
    //error
}

现在的理论是 scanf return 的成功写入尝试,所以如果我输入负数, scanf 不应该 return 2. 我的理论好像不对,为什么?

显然我可以简单地 scanf %d 然后检查 %d 是否为负但现在我很好奇为什么我最初的理论是不正确的。那么有没有不用扫描再对比的方法呢?

您的理论不成立,因为 scanf 不会失败或不会拒绝将用户输入复制到指定的内存地址,即使在预期输入无符号数字时输入有符号数字也是如此。因此,根据 scanf 文档,scanf 会将 return 项目数复制到提供的内存地址。

如果输入的数字不正确

scanf() 仍然会成功(并增加 return 值)。

比如scanf("%u", &my_unsigned_int);读取文本“-1”,就会return1,my_unsigned_int会写成likemy_unsigned_int = (unsigned int) -1;

如果他们输入十进制值,也会出现这种情况 - 它将通过类型转换分配给您的 int 字段。看起来您没有排除浮点数,所以您可能只想 scanf("%f", &some_float); 然后检查 some_float.

的值

My theory seems to be incorrect, why?

%u 用作格式说明符时,scanf 期望(来自 http://en.cppreference.com/w/cpp/io/c/fscanf):

The format of the number is the same as expected by strtoul() with the value 10 for the base argument.

strtoul documentation 关于负数是这样说的:

If the minus sign was part of the input sequence, the numeric value calculated from the sequence of digits is negated as if by unary minus in the result type, which applies unsigned integer wraparound rules.

因此,即使您输入负数,%u 也不会失败。