2016-12-15 76 views
2

我的目标是扫描一些阳性仅a,如果输入负数,则函数应该打印错误过滤掉负数:使用scanf函数

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

现在的理论是,scanf返回成功的写作尝试,所以如果我输入负数,scanf不应该返回2.我的理论似乎不正确,为什么?

很明显,我可以简单地scanf%d然后检查是否%d是否定的,但现在我很好奇为什么我的最初理论是不正确的。那么有没有一种方式没有扫描,然后比较?

+0

您是否阅读过['scanf'文档](http://www.cplusplus.com/reference/cstdio/scanf),主要是* Return Value *部分?你还检查了'a'的价值吗? –

+0

是的,我读过它了。“成功时,函数返回成功填充的参数列表项数。”所以基本上,如果它成功扫描了两个参数,它将返回2.所以我认为,如果我给'scanf'一个负数,当它期望'unsigned int'时,它不应该成功扫描。 –

+0

该部分有多个句子:*“由于匹配失败,读取错误或文件结束的范围,此计数可以匹配预期的项目数量或更少(甚至为零)。” 如果在读取时发生读取错误或达到文件结束,则设置正确的指示符(feof或ferror)。如果在任何数据可能成功读取之前发生错误,则返回EOF 如果编码错误发生在解释宽字符时,函数将errno设置为EILSEQ。“* –

回答

2

由于scanf不会失败或不拒绝将用户输入复制到指定的内存地址,即使在输入有符号数字时也会出现无符号数字。因此,根据scanf文档,scanf将返回复制到提供的内存地址的项目数。

+0

它为什么不失败?它是否简单地将'signed int'转换为'unsigned int'? –

+0

这是一个未定义的行为。它可能会转换为正数(无符号),或者可能不会。 – VHS

0

scanf()如果输入不正确类型的号码仍然成功(并增加返回值)。

例如,如果scanf("%u", &my_unsigned_int);朗读课文“-1”,它将返回1和my_unsigned_int将被写入到喜欢my_unsigned_int = (unsigned int) -1;

这也将是如此,如果他们进入一个十进制值 - 将被分配通过类型转换将其转换为int字段。它看起来并不像你排除花车,所以你可能只想scanf("%f", &some_float);,然后检查some_float的值。

2

My theory seems to be incorrect, why?

%u用作格式spefifier,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说,这大约负numbeers:

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甚至不失败当你输入一个负数。