最稳妥读整数的方法是std::getline()配合std::stoi()并捕获std::invalid_argument和std::out_of_range异常,可处理格式错误、溢出及前导空白,避免缓冲区残留问题。

用 std::cin 读整数最直接,但得先处理输入缓冲区残留
直接写 std::cin >> n; 多数情况下能工作,但如果你之前用过 std::getline() 或混用 C 风格输入(比如 scanf()),std::cin 会卡在换行符上,看似“没反应”——其实它读到了空格/换行就停了,没清掉。
常见错误现象:std::cin >> n; 看似跳过、程序直接往下走、n 值还是旧的或未定义。
- 用
std::cin.ignore()清缓冲区:比如std::cin.ignore(std::numeric_limits<:streamsize>::max(), '\n');</:streamsize> - 更稳妥的做法是统一用
std::getline()读整行,再用std::stoi()转换,能捕获格式错误 - 如果确定只读一个整数且后续无其他输入,
std::cin >> n;后加std::cin.ignore();(默认忽略一个字符)通常够用
用 std::getline() + std::stoi() 更健壮,适合带校验场景
当用户可能输错(比如字母、空格开头、多空格分隔),std::stoi() 会抛 std::invalid_argument 或 std::out_of_range,比 std::cin 默默失败更容易调试。
使用场景:命令行工具、交互式小练习、需要提示“请输入有效数字”的场合。
立即学习“C++免费学习笔记(深入)”;
-
std::string line;→std::getline(std::cin, line); -
try { int n = std::stoi(line); }捕获异常 -
std::stoi()忽略前导空白,但遇到第一个非法字符就停;想严格要求整行只能是数字,得手动检查line.find_first_not_of("0123456789- ") != std::string::npos
用 scanf() 的 C 风格写法,注意返回值必须检查
scanf("%d", &n) 看似简单,但返回值不为 1 就说明没读到有效整数——这点常被忽略,导致 n 值未定义。
性能上它比 std::cin 快一点,但兼容性和类型安全差;在竞赛中常见,工程代码里不推荐。
- 永远检查
if (scanf("%d", &n) != 1) { /* 处理错误 */ } - 如果前面有
std::cin混用,务必调用fflush(stdin)(不跨平台)或先用__fpurge(stdin)(Linux)或rewind(stdin)(Windows)——但更建议别混用 -
%d不吃换行符,下次scanf可能直接读到旧的回车,行为不稳定
整数溢出和范围检查不能靠直觉,尤其用 std::stoi() 时
std::stoi() 在超出 int 范围时抛 std::out_of_range,但很多人只 catch std::invalid_argument,漏掉溢出情况。
比如输入 "2147483648"(INT_MAX+1),在 32 位系统上必然溢出;而 std::cin >> n 对溢出会静默设为 INT_MAX 或 INT_MIN 并置 failbit,但不报异常。
- 用
std::stoi()必须同时 catchstd::invalid_argument和std::out_of_range - 若需支持更大整数,改用
std::stoll()+long long,并注意输出也得用对应格式(如%lld或std::to_string()) -
std::cin的溢出可通过if (std::cin.fail())检测,之后要std::cin.clear()和std::cin.ignore(...)才能继续用
实际写的时候,多数人卡住不是语法不会,而是没意识到输入函数背后有缓冲区状态、错误标志、异常边界这些隐形开关。把 std::cin 当黑盒用,迟早撞上换行符和溢出问题。


















