You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

scanf读取%d时输入仅负号为何失败却消耗符号?

scanf读取数值时符号被消耗但返回匹配失败的原因

测试代码

int x;
int ret = scanf("%d", &x);
char ch;
scanf("%c", &ch);
printf("%c, %d\n", ch, ret);

输入与输出

  • 输入:
-*
  • 输出:*, 0

疑问

输入-*时,首次读取整数x返回0(匹配失败),但负号被消耗;换成正号也会出现相同情况,但其他字符不会。请问该符号是否被视为整数的开头?若是为何判定失败?若不是为何被消耗?还是未定义行为?另外使用double类型时输入.也会出现相同问题。


解析

这是scanf的标准规定行为,并非未定义行为。

针对整数格式%d的情况

  • scanf处理%d时,会先跳过空白字符,然后尝试匹配整数的可选符号(+或-),之后需要匹配数字字符来构成完整整数。
  • 当输入是-*时,scanf会先读取-(因为它是整数的合法起始符号),但后续的*不是数字,无法构成有效整数,因此匹配失败。此时scanf会把*放回输入缓冲区,但已经读取的-不会回退——这就是第二个scanf("%c")读取到*而非-的原因。
  • 这种场景下,scanf返回0,表示没有成功匹配任何完整的输入项(因为有效整数未被读取完成)。

针对浮点数格式%lf的情况

  • 浮点数的合法起始包括:可选符号、数字,或者单独的.(比如.123是合法的浮点数)。当输入.后跟随非数字字符时,scanf会读取.,但后续无法匹配数字,导致匹配失败,.被消耗,剩余字符留在缓冲区。

总结

  • +/-是整数的合法起始部分,.是浮点数的合法起始部分;
  • 当这些符号后没有跟上合法的数字时,scanf会消耗这些符号,但因无法构成完整的数值,所以返回匹配失败;
  • 这完全是C标准规定的scanf匹配逻辑,属于预期行为。

内容的提问来源于stack exchange,提问作者GKxx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:42:43