讲师中心 微信公众号

工具推荐

视频效率加速
剧云
剧云

中文短剧剧本制作平台

Laper
Laper

剧本策划到成片协作

updream

一键生成高质量推广成片

AniShort
AniShort

AI短剧协同制作平台

C++ 怎么从字符串提取数字 C++ stoi与stod异常处理教程【健壮性】

老磊吖_7362

老磊吖_7362

发布时间:2026-01-29 14:05:01

|

265人浏览过

|

来源于php中文网

原创

stoi/stod 不加防护必出错,因它们严格校验格式且不返回解析位置;安全解析需用 strtol/strtod 获取结束指针,或手动扫描提取数字子串并捕获异常。

c++ 怎么从字符串提取数字 c++ stoi与stod异常处理教程【健壮性】

直接用 stoi 或 stod 解析字符串里的数字,只要输入含非数字字符(比如 "123abc"、" 45.6"、空串、纯空格),程序就崩溃或行为未定义——这不是“能不能用”的问题,是“不加防护就一定出事”。

stoi/stod 默认只认前导空白 + 符号 + 数字,其余全算错误

这两个函数底层依赖 std::strtol/std::strtod,规则很严格:

  • "123" → 成功;"123abc" → 抛 std::invalid_argument(不是截取 123)
  • " 45.6" → 成功(自动跳过前导空格);"\t\n45.6" → 同样成功
  • " " 或 "" → 抛 std::invalid_argument
  • "1e1000"(溢出)→ 抛 std::out_of_range

它们**不提供“解析到哪为止”的位置信息,也不容忍尾部垃圾字符**。想安全提取,必须自己控制解析边界。

用 strtol/strtod 替代,拿到解析结束位置再判断

strtol 和 strtod 是 C 标准库函数,但 C++ 中仍可直接用,优势是返回 char* 指向第一个未转换字符,你能据此判断是否“整段合法”或“只取前面有效部分”:

立即学习“C++免费学习笔记(深入)”;

Gitguard Skill
Gitguard Skill

Git 安全扫描与仓库健康审计 — 基于熵的密钥检测、复合健康评分、提交质量分析、陈旧分支清理以及依赖扫描

下载
std::string s = "123abc";
char* end;
long val = std::strtol(s.c_str(), &end, 10);
if (end == s.c_str()) {
    // 一个数字都没识别到(如空串、纯字母)
} else if (*end == '\0') {
    // 全部字符都参与了转换 → 完全合法
} else {
    // end 指向 'a',说明 "123" 是有效前缀,后面是垃圾
}

注意:strtol 不抛异常,错误时返回 0 或 LONG_MIN/LONG_MAX 并设置 errno;strtod 同理,但需检查 errno == ERANGE 判断溢出。

提取“字符串中第一个连续数字子串”要手动扫描

如果原始需求是像从 "price: $123.45 (tax included)" 中捞出 123.45,stoi/stod 完全无能为力——它们要求整个字符串符合格式。此时得自己遍历:

  • 跳过开头非数字、非符号、非小数点的字符
  • 记录起始位置,继续读直到遇到非法字符(如字母、多于一个小数点、连着两个符号)
  • 对截出的子串调用 stod,并用 try/catch 捕获溢出

示例关键逻辑:

size_t i = 0;
// 跳过非起始字符
while (i < s.length() && !std::isdigit(s[i]) && s[i] != '-' && s[i] != '+') ++i;
size_t start = i;
// 扫描数字主体(允许一个 '.',不允许 "1.2.3")
int dot_count = 0;
while (i < s.length()) {
    if (std::isdigit(s[i])) {
        ++i;
    } else if (s[i] == '.' && dot_count == 0) {
        ++dot_count;
        ++i;
    } else {
        break;
    }
}
if (i > start) {
    std::string num_str = s.substr(start, i - start);
    try {
        double d = std::stod(num_str);
        // 使用 d
    } catch (const std::exception&) {
        // 溢出或格式异常(如 ".e")
    }
}

别忽略 locale 和负号嵌套等边界情况

默认 C locale 下 strtol 认 "-123",但若程序切换过 locale(比如用了 std::locale::global(std::locale("zh_CN"))),某些 locale 可能允许千分位符号或不同负号,导致解析错位。更隐蔽的是:"--123"、"-+45" 这类输入,strtol 会停在第一个 '-' 后,认为无效,但你可能期望跳过所有前导符号——这只能靠预处理。健壮性真正的难点不在“怎么转”,而在“怎么定义什么是‘可接受的输入’”。

热门AI工具

更多
PixPix
PixPix Hot

PixPix是一款面向电商视觉生产的AI商品图生成工具。

火山引擎

火山引擎是一款面向企业的云计算与AI服务平台。

豆包大模型

豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

切问学术

切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

DeepSeek

DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

超级麦吉

一款通过数字员工协作完成调研、数据分析与文档制作的AI办公平台。

WorkBuddy

一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

Atoms
Atoms Hot

Atoms是一款AI智能体工具,第一支自动构建真实业务的 AI 团队。

小橡皮AI

一款AI工具,主要用于小橡皮一键去AI味,将机器味重的内容改得更有活人感,防止因为 AI 内容被平台打上 AI 标签,以及限流,适合需要提升相关任务效率的用户。

相关专题

更多
js 字符串转数组
js 字符串转数组

js字符串转数组的方法:1、使用“split()”方法;2、使用“Array.from()”方法;3、使用for循环遍历;4、使用“Array.split()”方法。本专题为大家提供js字符串转数组的相关的文章、下载、课程内容,供大家免费下载体验。

1918

2023.08.03

js截取字符串的方法
js截取字符串的方法

js截取字符串的方法有substring()方法、substr()方法、slice()方法、split()方法和slice()方法。本专题为大家提供字符串相关的文章、下载、课程内容,供大家免费下载体验。

3144

2023.09.04

java基础知识汇总
java基础知识汇总

java基础知识有Java的历史和特点、Java的开发环境、Java的基本数据类型、变量和常量、运算符和表达式、控制语句、数组和字符串等等知识点。想要知道更多关于java基础知识的朋友,请阅读本专题下面的的有关文章,欢迎大家来php中文网学习。

6364

2023.10.24

字符串介绍
字符串介绍

字符串是一种数据类型,它可以是任何文本,包括字母、数字、符号等。字符串可以由不同的字符组成,例如空格、标点符号、数字等。在编程中,字符串通常用引号括起来,如单引号、双引号或反引号。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

6489

2023.11.24

java读取文件转成字符串的方法
java读取文件转成字符串的方法

Java8引入了新的文件I/O API,使用java.nio.file.Files类读取文件内容更加方便。对于较旧版本的Java,可以使用java.io.FileReader和java.io.BufferedReader来读取文件。在这些方法中,你需要将文件路径替换为你的实际文件路径,并且可能需要处理可能的IOException异常。想了解更多java的相关内容,可以阅读本专题下面的文章。

8034

2024.03.22

php中定义字符串的方式
php中定义字符串的方式

php中定义字符串的方式:单引号;双引号;heredoc语法等等。想了解更多字符串的相关内容,可以阅读本专题下面的文章。

12434

2024.04.29

go语言字符串相关教程
go语言字符串相关教程

本专题整合了go语言字符串相关教程,阅读专题下面的文章了解更多详细内容。

6439

2025.07.29

c++字符串相关教程
c++字符串相关教程

本专题整合了c++字符串相关教程,阅读专题下面的文章了解更多详细内容。

7227

2025.08.07

Go-Zero API开发使用教程
Go-Zero API开发使用教程

本专题聚焦Go-Zero的API开发,拆解.api描述文件的语法结构、路由与分组定义、参数绑定与校验规则,说明统一响应体、JWT鉴权、跨域与接口文档生成的落地方式,并给出网关聚合与接口测试的实践建议。

0

2026.11.12

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
Postman Native Git工作流指南
Postman Native Git工作流指南

共0课时 | 0人学习

vscode手册
vscode手册

共0课时 | 0人学习

Git 教程
Git 教程

共21课时 | 8.2万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn