cin.clear()仅清除流状态标志位(failbit等),不清理缓冲区;必须配合cin.ignore()丢弃非法字符,否则后续输入仍失败。

cin.clear() 清除的是流的状态标志位,不是缓冲区内容
cin.clear() 只重置 failbit、badbit、eofbit 这些错误状态位,把流“标记”为可继续读取的状态。它不碰缓冲区里一个字节——哪怕你刚输了个 "abc" 导致 cin >> num 失败,调完 cin.clear() 后,'a'、'b'、'c' 仍原封不动卡在缓冲区里。
典型错误现象:
- 输入
abc后cin >> x失败 → 调cin.clear()→ 紧接着再cin >> x,依然立刻失败,且不等待新输入 - 后续
getline(cin, s)直接读到空行(因为残留的'\n'或非法字符被跳过或吞掉)
为什么只清状态不够用
流进入 failbit(比如类型不匹配)后,后续所有提取操作(>>)会直接跳过执行,返回自身,不做任何读取——这是 C++ 标准行为。你清了标志位,但没动缓冲区,下一次 >> 遇到的还是那个 'a',立刻再次触发 failbit。
所以必须配对使用:
立即学习“C++免费学习笔记(深入)”;
-
cin.clear():让流“愿意干活” -
cin.ignore(numeric_limits<streamsize>::max(), '\n')</streamsize>:把缓冲区里从当前位置直到换行符(含)的所有垃圾字符丢掉
cin.clear() 的参数和默认行为
cin.clear() 等价于 cin.clear(ios_base::goodbit),即把状态设为“一切正常”。你也可以手动传其他值,比如 cin.clear(ios_base::failbit) 来**故意**设错——但这几乎没人这么干。
注意:cin.clear(0) 是合法写法,但语义等同于 cin.clear();不要写 cin.clear(1) 或任意非标准值,结果未定义。
别用 cin.sync() 替代 ignore()
有些老代码用 cin.sync() 想清缓冲区,但它在标准中行为未完全规定:某些编译器(如 libstdc++)下它可能无效,或仅清空底层 C stdio 缓冲区,不保证影响 cin 的缓冲逻辑。C++11 之后,cin.sync() 已不推荐,ignore() 是唯一可移植、可预测的选择。
真正可靠的恢复输入流程就两步,缺一不可:先 cin.clear(),再 cin.ignore(numeric_limits<streamsize>::max(), '\n')</streamsize>。漏掉 ignore,等于只拧开了瓶盖,水还在瓶子里堵着。


















