标准 C 中无便携的字符串到浮点转换错误检测方法
问题概述
标准 C 的 strtod 及相关函数在错误检测、区域设置兼容性和边缘值处理方面存在根本性缺陷,开发者难以以便携方式可靠地解析字符串为浮点数并捕获错误。多个评论者指出,locale 依赖、errno 机制不可靠、denormal 值的 ERANGE 标记以及缺乏两值返回 API 都导致了实际开发中的痛点,迫使人们转而使用 std::from_chars 或第三方库。
痛点标签
- Locale-dependent parsing: 当开发者机器与目标系统 locale 不同时,本应小数点的字符可能变成逗号,导致数字解析失败或错误。
- Unreliable error reporting: 函数返回值和 errno 机制不可靠,迫使开发者不得不使用 'don't care' 的方式或手动检查全局状态,API 设计缺失。
- Denormal/underflow edge cases: strtod 对 denormal 设置 ERANGE,即使这些值是合法的,且不同实现行为不一,导致字符串回环转换失败。
- Lack of convenient two-value return: 标准 C 无法优雅地同时返回解析结果和错误状态,开发者被迫陈旧的 errno 模式或直接忽略错误。
待验证问题
- 你是否在实际部署环境中遇到过 locale 导致的数字解析问题?
- 一个能可靠报告转换错误并统一处理 denormal 的便携包装库对你的工作流有价值吗?
- 你目前是否使用或会考虑转向 std::from_chars 或第三方库进行字符串到数字转换?
证据
原话 · @anonymous
C number parsing functions are fundamentally broken, since they are locale-dependend. There are many bugs when one parses a number assuming it has decimal point, but later on systems with locale different from one used on developer's machine it may be suddenly comma instead of point. So, one should avoid using them almost always and use std::from_chars (available in new C++ versions) or some other thirdparty library.
原话 · @anonymous
[double x, errno_t errno] = strtod(s, nullptr); if (errno != 0) { ... } [x, _] = strtod(s, nullptr); // When you're certain the error is impossible or just don't care Instead, we're stuck with "check if the return value is -1 and if it is, check the global variable errno" at best, and with "the function doesn't really reliably reports its errors so don't feed it malformed data, idc" at worst.
原话 · @anonymous
Denormals therefore count as underflow and strtod() sets ERANGE for them, even though they they are legitimate values to store as strings and parse back. Some implementations of strtod() return the correct floating-point value for these, while setting ERANGE. Others discard the value and return 0.0, preventing them from being round-tripped to strings.
原话 · @anonymous
When I was writing some ASM for a microcontroller to do string <--> float conversion, I could find almost nothing on how to best perform the operations. There were essentially three ways to do it. Muddle through with a naive implementation. Look at the ASM of an old 8-bit machine. The final category was the by far the most dominant suggestion, to the point that anything else is almost like lost knowledge now. That solution was to use the C standard functions. It seems like this is a sufficiently unpleasant task that as soon as anyone didn't absolutely have to do it all themselves, the punted to a black box solution.
免责声明:本卡片由 AI 从社区讨论中提炼,属于「痛点证据」,是需求分析与验证的起点,不等同于「已验证的市场需求」。AI 存在分析局限,关键决策前请打开上方原始讨论人工复核。