std::stof转换失败时抛std::invalid_argument异常,值超出范围时抛std::out_of_range异常,二者均会导致程序终止,必须用try-catch捕获。

std::stof 转换失败时抛什么异常
直接调用 std::stof 但字符串含非法字符(如 "12.34abc" 或空串 ""),会抛出 std::invalid_argument;若值超出 float 表示范围(如 "1e50"),则抛 std::out_of_range。这两种异常都来自 <exception></exception>,不捕获会导致程序终止。
实际建议用 try-catch 包裹,且优先检查输入是否为空或全空白:
- 用
str.find_first_not_of(" \t\n\r") == std::string::npos判断纯空白 - 避免依赖
pos参数做“部分解析”——std::stof(str, &pos)在遇到首个非法字符后停止,但不会报错,容易掩盖格式问题 - 若需容忍尾部垃圾字符(如单位
"3.14kg"),应先用正则或手动截取数字前缀,再传给stof
std::to_string 输出 float 精度失控怎么办
std::to_string 对 float 的输出固定为 6 位有效数字(不是小数位),且自动四舍五入。例如 std::to_string(1.23456789f) 得到 "1.234568",而 std::to_string(0.1f) 会输出 "0.100000" —— 看似精确,实则是浮点二进制表示的固有误差被简单截断后的假象。
真正需要可控精度时,别用 to_string:
立即学习“C++免费学习笔记(深入)”;
- 用
std::ostringstream配合std::setprecision和std::fixed,比如ss - 若仅需快速转且接受默认行为,
to_string安全、无异常、头文件只需<string></string> - 注意:
to_string输入是float时,内部先转成double再格式化,所以1.23456789f和1.23456789(double 字面量)转出结果可能不同
char* 能直接传给 std::stof 吗
不能。std::stof 只接受 std::string 或 C 风格字符串(const char*),但后者必须以 null 结尾且内容合法。常见误用是把未初始化或越界的 char[] 直接传入,导致未定义行为。
安全做法分三类:
- 已有
std::string:直接std::stof(s) - 已有 null 结尾的
const char*(如argv[1]):可直接std::stof(cstr) - 已有非 null 结尾的缓冲区(如
char buf[32]读自文件):先构造std::string(buf, len)再传入,避免扫描越界
别用 std::atof 替代——它不抛异常,错误时静默返回 0.0f,极难调试。
为什么 stof 和 to_string 不配对使用
它们语义不对称:std::stof 解析的是人类可读的十进制文本(支持科学计数法、前导空格、正负号),而 std::to_string 输出的是固定精度的十进制近似值,且无法还原原始二进制值。例如:
float f = 0.1f; std::string s = std::to_string(f); // "0.100000" float g = std::stof(s); // g != f(因 0.1f 本身已是近似)
这不是 bug,而是浮点表示的本质限制。若需 round-trip 精确,必须用二进制序列化(如 memcpy(&bytes, &f, sizeof(float))),而非字符串中介。
日常场景中,只要明确“字符串只是展示/传输媒介,不是存储格式”,就别指望 stof + to_string 能构成闭环。真正要保精度,得从源头控制输入格式,或改用 double + 更高精度输出流。


















