std::from_chars
在标头 <charconv> 定义
|
||
std::from_chars_result from_chars( const char* first, const char* last, |
(1) | (C++17 起) (C++23 起 constexpr) |
(2) | ||
std::from_chars_result from_chars( const char* first, const char* last, float& value, |
(C++17 起) (C++23 前) |
|
std::from_chars_result from_chars( const char* first, const char* last, |
(C++23 起) | |
按照后述模式分析字符序列 [
first,
last)
。如果没有字符与模式匹配或按照分析匹配字符获得的值不能以 value 的类型表示,那么不会修改 value,否则将与模式匹配的字符转译成算术值的文本表示,并将值存储到 value。
- 在 base 是 16 时不识别 "0x" 或 "0X" 前缀
- 只识别负号(不识别正号),而且只针对 value 的有符号整数类型。
- 不识别指数外的正号(在起始位置只允许出现负号)
- 如果 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")。
标准库提供所有以无 cv 限定的浮点类型作为参数 value 的被引用类型的重载。
|
(C++23 起) |
参数
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 演示: auto to_int = [](std::string_view s) -> std::optional<int> { int value{}; if (std::from_chars(s.begin(), s.end(), value).ec == std::errc{}) 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> 的公开成员函数) |