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

为何C++中try-catch无法捕获std::stoull的异常?

解决std::stoull对部分非法输入不抛出异常的问题

问题原因

std::stoull的默认行为是读取到第一个非法字符就停止解析:只要输入开头存在合法的数值字符,它就会返回已解析的部分结果,不会触发异常。比如你的输入6yh45gu94j5vun,它会解析开头的合法16进制字符6,返回数值6,而非因为后续的y抛出异常。

只有两种情况stoull会抛出异常:

  • 输入中完全没有合法数值字符(比如全是字母或符号)
  • 解析出的数值超出unsigned long long的范围(溢出)

解决方案

要确保整个字符串都是合法的16进制字符,需要利用stoull的第二个参数(size_t* pos)记录解析停止的位置,再通过这个位置判断是否整个字符串都被合法解析。

修改后的代码示例:

#include <iostream>
#include <exception>
#include <string>
#include <sstream>

using namespace std;

int main() {
    stringstream ss("6yh45gu94j5vun:");
    string valueStr;
    if (!getline(ss, valueStr, ':')) {
        return -1;
    }
    unsigned long long value;
    try {
        size_t pos;
        value = stoull(valueStr, &pos, 16);
        // 检查是否整个字符串都被解析完成
        if (pos != valueStr.size()) {
            throw invalid_argument("存在非法字符");
        }
    } catch (const exception& e) {
        cout << -1;
        return -1;
    }
    cout << value;
    return 0;
}

关键修改说明

  • 新增size_t pos变量,传给stoull的第二个参数,它会存储解析停止的索引位置。
  • 解析完成后判断pos是否等于valueStr.size():相等则说明整个字符串都是合法16进制字符;不等则说明中途遇到非法字符,手动抛出invalid_argument异常触发错误处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:52:08