std::from_chars
来自cppreference.com
| 在标头 <charconv> 定义
|
||
| |
(1) | (C++17 起) (C++23 起为 constexpr) |
| |
(2) | |
按照后述模式分析字符序列 [first, last)。如果没有字符与模式匹配或按照分析匹配字符获得的值不能以 value 的类型表示,那么不会修改 value,否则将与模式匹配的字符转译成算术值的文本表示,并将值存储到 value。
1) 整数分析函数:期待等同于 std::strtol 在默认("C")本地环境所使用者相同的模式,并给定非零整数底,除了
- 在
base是 16 时不识别 "0x" 或 "0X" 前缀 - 只识别负号(不识别正号),而且只针对
value的有符号整数类型。 - 不忽略前导空白。
char 作为形参 value 的被引用类型的重载。2) 浮点数分析函数:期待期待等同于 std::strtod 在默认("C")本地环境所使用者相同的模式,除了
- 不识别指数外的正号(在起始位置只允许出现负号)
- 如果
fmt设置了 std::chars_format::scientific 但没设置 std::chars_format::fixed,那么要求指数部分(否则可选) - 如果
fmt设置了 std::chars_format::fixed 但没设置 std::chars_format::scientific,那么不允许可选的指数部分 - 如果
fmt是 std::chars_format::hex,那么不允许前缀 "0x" 或 "0X"(字符串 "0x123" 分析为值 "0" 和未分析的剩余 "x123")。 - 不忽略前导空白。
任何情况下,按照 std::round_to_nearest 舍入后,结果值是最多两个最接近匹配模式的字符串的值的浮点数之一。
标准库提供所有以无 cv 限定的标准(C++23 前)浮点数类型作为形参
value 的被引用类型的重载。参数
| first, last | - | 要分析的有效字符范围 |
| value | - | 用于在分析成功时存储被分析值的输出形参 |
| base | - | 使用的整数底数:为 2 与 36 间的值(含上下限)。 |
| fmt | - | 使用的浮点数格式,为 std::chars_format 类型的位掩码 |
返回值
成功时,返回 std::from_chars_result 类型的值,它的 ptr 指向首个与模式不匹配的字符,或者在所有字符都匹配时指向拥有等于 last 的值,并值初始化 ec。
如果没有匹配到任何模式,那么返回 std::from_chars_result 类型的值,它的 ptr 等于 first 且 ec 等于 std::errc::invalid_argument。不修改 value。
如果匹配到模式,但被分析值不在 value 的类型所表示的范围内,那么返回 std::from_chars_result 类型的值,它的 ec 等于 std::errc::result_out_of_range 且 ptr 指向首个不匹配模式的字符。不修改 value。
异常
不抛出。
注解
与 C++ 和 C 库中的其他格式化函数不同,std::from_chars 是独立于本地环境、不分配、不抛出的。它只提供其他库(例如 std::sscanf)所用策略的一个小子集。它的目的是在常见的高吞吐量环境,例如基于文本的交换(JSON 或 XML)中,允许尽可能快的实现。
只有在两个函数都来自同一实现的情况下,才保证 std::from_chars 能恢复每个由 std::to_chars 格式化的浮点数。
由无后随数位的符号组成的模式被当做不匹配任何内容的模式。
| 功能特性测试宏 | 值 | 标准 | 功能特性 |
|---|---|---|---|
__cpp_lib_to_chars |
201611L |
(C++17) | 初等字符串转换(std::from_chars,std::to_chars)
|
202306L |
(C++26) | 检测 <charconv> 函数是否成功 | |
__cpp_lib_constexpr_charconv |
202207L |
(C++23) | 向 std::from_chars 和 std::to_chars 对于整数类型的重载添加 constexpr 修饰符
|
示例
运行此代码
#include <cassert>
#include <charconv>
#include <iomanip>
#include <iostream>
#include <optional>
#include <string_view>
#include <system_error>
int main()
{
for (std::string_view const str : {"1234", "15 foo", "bar", " 42", "5000000000"})
{
std::cout << "字符串: " << std::quoted(str) << "。";
int result{};
auto [ptr, ec] = std::from_chars(str.data(), str.data() + str.size(), result);
if (ec == std::errc())
std::cout << "结果: " << result << ", ptr -> " << std::quoted(ptr) << '\n';
else if (ec == std::errc::invalid_argument)
std::cout << "这不是数值。\n";
else if (ec == std::errc::result_out_of_range)
std::cout << "这个数值大于 int。\n";
}
// C++23 的 constexpr from_char 演示 / C++26 的 operator bool() 演示:
auto to_int = [](std::string_view s) -> std::optional<int>
{
int value{};
#if __cpp_lib_to_chars >= 202306L
if (std::from_chars(s.data(), s.data() + s.size(), value))
#else
if (std::from_chars(s.data(), s.data() + s.size(), value).ec == std::errc{})
#endif
return value;
else
return std::nullopt;
};
assert(to_int("42") == 42);
assert(to_int("foo") == std::nullopt);
#if __cpp_lib_constexpr_charconv and __cpp_lib_optional >= 202106
static_assert(to_int("42") == 42);
static_assert(to_int("foo") == std::nullopt);
#endif
}
输出:
字符串: "1234"。结果: 1234, ptr -> ""
字符串: "15 foo"。结果: 15, ptr -> " foo"
字符串: "bar"。这不是数值。
字符串: " 42"。这不是数值。
字符串: "5000000000"。这个数值大于 int。
缺陷报告
下列更改行为的缺陷报告追溯地应用于以前出版的 C++ 标准。
| 缺陷报告 | 应用于 | 出版时的行为 | 正确行为 |
|---|---|---|---|
| LWG 2955 | C++17 | 此函数在 <utility> 并使用 std::error_code | 移动到 <charconv> 并使用 std::errc |
| LWG 3373 | C++17 | std::from_chars_result 可能拥有额外的成员
|
禁止额外的成员 |
参阅
(C++17) |
std::from_chars 的返回类型 (类) |
(C++17) |
转换整数或浮点数为字符序列 (函数) |
(C++11)(C++11)(C++11) |
转换字符串为有符号整数 (函数) |
(C++11)(C++11)(C++11) |
转换字符串为浮点数 (函数) |
(C++11) |
转换字节字符串为整数值 (函数) |
| 转换字节字符串为浮点值 (函数) | |
| 从 stdin、文件流或缓冲区读取有格式输入 (函数) | |
| 提取带格式数据 ( std::basic_istream<CharT,Traits> 的公开成员函数)
|