
cin >> short 时程序跳过输入或读出乱值
根本原因是 cin 默认按整数解析,但 short 类型容量小,若输入数字超出 short 范围(-32768 ~ 32767),cin 不会自动截断,而是置位 failbit,后续所有输入操作都会直接失败——你看到的“跳过”其实是流已失效,不是没输完。
- 验证是否失败:
if (!cin) { cin.clear(); cin.ignore(1000, '\n'); }必须加,否则下次cin >>仍无效 - 别用
cin >> (short)x强制转换:C++ 不允许对右值做流提取,编译直接报错no match for operator>> - 输入前确保缓冲区干净:尤其在
cin >> int后立刻读short,换行符残留会导致cin >> short立即失败
正确读取 short 的三种写法(按推荐顺序)
最稳的方式不是硬塞 short,而是先读进更大类型再检查范围。C++ 流不提供原生 short 安全读取接口,得自己兜底。
- 推荐:先读
int,再判断范围并赋值:int tmp; if (cin >> tmp && tmp >= -32768 && tmp <= 32767) { short x = static_cast<short>(tmp); } else { cin.clear(); cin.ignore(1000, '\n'); // 处理错误 } - 次选:用
std::stoi配合字符串读取,能捕获std::out_of_range:string s; if (cin >> s) { try { short x = static_cast<short>(stoi(s)); } catch (const std::out_of_range&) { // 超出 int 范围,更别说 short } } - 不推荐:直接
cin >> x(x是short)——除非你 100% 确保输入永远在范围内,且不关心用户输错
为什么不能依赖 cin 的 type conversion 自动适配
cin 对内置类型的提取操作符是模板特化实现的,operator>>(istream&, short&) 确实存在,但它只负责把字符序列转成数值并存入 short 内存,**不做范围校验**。溢出时行为是未定义的(实际常表现为静默截断或设 failbit),和 int 或 long long 一样,C++ 标准没要求它抛异常或提示。
- 不同编译器表现可能不同:GCC 可能设
failbit,MSVC 有时会截断低 16 位,导致值完全不对 -
sizeof(short)不一定是 2 字节(虽然绝大多数平台是),依赖INT16_MIN/MAX更可靠 - 如果用
scanf("%hd", &x),同样不校验范围,且格式符写错(如%d)会直接内存越界
cin.clear() 和 cin.ignore() 必须成对出现
只要 cin >> 返回 false(比如输了个字母或超限数字),流就卡在 fail 状态,不清除标志位,后面所有输入都无效——这不是 bug,是设计如此。但很多人只清标志位,忘了清缓冲区里的非法字符,结果下一次读取立刻又失败。
立即学习“C++免费学习笔记(深入)”;
-
cin.clear()只重置状态位,不删缓冲区内容 -
cin.ignore(n, delim)才真正吃掉字符;常用cin.ignore(1000, '\n')清到行尾,1000 是防无限阻塞的安全上限 - 漏掉其中任一调用,错误输入后程序大概率进入“假死”:看似在等输入,其实
cin已拒绝服务
short,都是为节省内存批量处理数组或网络协议字段。真要读,就老实用 int 中转+范围检查——省下的那两个字节,远不如一次静默溢出带来的调试成本高。









