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

std::stoi解析含非数字字符字符串不抛异常,求纯数字专属解析函数

好问题!C++标准库本身并没有直接提供这种「严格匹配纯数字字符串」的转换函数,但我们可以基于现有工具轻松实现这个需求,给你分享几种常用的靠谱方案:

方案1:先校验字符合法性再调用std::stoi

这个思路最直观:先检查字符串是否完全由数字组成(可选支持负号),确认合法后再调用std::stoi转换。

#include <string>
#include <stdexcept>

int strict_stoi(const std::string& str) {
    // 处理空字符串的情况
    if (str.empty()) {
        throw std::invalid_argument("输入字符串为空");
    }

    size_t start_idx = 0;
    // 支持负整数:如果首字符是'-',从第二个字符开始检查
    if (str[0] == '-') {
        start_idx = 1;
        // 单独一个'-'属于非法输入
        if (start_idx == str.size()) {
            throw std::invalid_argument("仅包含负号,不是合法整数");
        }
    }

    // 检查从start_idx开始的所有字符是否都是数字
    if (str.find_first_not_of("0123456789", start_idx) != std::string::npos) {
        throw std::invalid_argument("字符串包含非数字字符");
    }

    // 确认合法后调用stoi转换
    return std::stoi(str);
}

如果只需要支持正整数,直接去掉负号相关的逻辑即可。

方案2:用std::strtol检查解析结束位置

C标准库的strtol函数会返回解析终止的指针,我们可以通过判断这个指针是否指向字符串末尾,来确认是否所有字符都被解析为数字,同时还能处理整数溢出的情况。

#include <string>
#include <cstdlib>
#include <stdexcept>
#include <climits>
#include <cerrno>

int strict_stoi(const std::string& str) {
    char* end_ptr = nullptr;
    errno = 0; // 重置错误标记

    // 解析字符串为长整数
    long parsed_val = std::strtol(str.c_str(), &end_ptr, 10);

    // 检查四种非法情况:
    // 1. 没有任何有效数字被解析
    // 2. 解析结束后还有剩余字符
    // 3. 解析结果超出long的范围
    // 4. 解析结果超出int的范围
    if (end_ptr == str.c_str() || *end_ptr != '\0' ||
        (errno == ERANGE && (parsed_val == LONG_MAX || parsed_val == LONG_MIN)) ||
        parsed_val < INT_MIN || parsed_val > INT_MAX) {
        throw std::invalid_argument("不是合法的整数字符串");
    }

    return static_cast<int>(parsed_val);
}

这个方案的优势是对错误情况的处理更全面,适合对稳定性要求高的场景。

方案3:用std::stringstream做流式解析

利用C++的输入流特性,尝试读取整数后,检查流是否到达末尾,以此判断是否有剩余的非数字字符。

#include <string>
#include <sstream>
#include <stdexcept>

int strict_stoi(const std::string& str) {
    std::istringstream iss(str);
    int parsed_val;
    char leftover_char;

    // 尝试读取整数,同时检查是否还有未读取的字符
    if (!(iss >> parsed_val) || (iss >> leftover_char)) {
        throw std::invalid_argument("不是合法的整数字符串");
    }

    return parsed_val;
}

注意:默认情况下,输入流会跳过开头的空白字符(比如空格、换行),如果你的场景不允许字符串包含任何空白,需要额外加入空白字符的校验逻辑。

内容的提问来源于stack exchange,提问作者D.Fonkaz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 08:22:12