<charconv> 函数

<charconv> 标头包括以下非成员函数:

非成员函数 描述
to_chars 将整数值或浮点值转换为 char 序列。
from_chars char 序列转换为整数值或浮点值。

这些转换函数针对性能进行了优化,还支持最短的往返行为。 最短往返行为意味着当数字转换为字符时,只写出足够的精度,以便在将这些字符转换回浮点值时恢复原始数字。

  • 将字符转换为数字时,数值不需要以 null 结尾。 同样,将数字转换为字符时,结果不会以 null 结尾。
  • 转换函数不分配内存。 你在所有情况下都拥有缓冲区。
  • 转换函数不会引发。 返回一个结果,可以据此确定转换是否成功。
  • 转换函数不区分运行时舍入模式。
  • 转换函数无法识别区域设置。 对于使用逗号的区域设置,它们总是将小数点输出并解析为 '.',而从不将其输出为“,”。

to_chars

将整数值或浮点值转换为 char 序列。

通过填充范围 [first, last) 将 value 转换为字符串,其中 [first, last) 必须是一个有效范围。 返回 to_chars_result 结构。 如果转换成功,如 to_char_result.ec 所示,成员 ptr 是写入字符的 one-past-the-end 指针。 否则,to_char_result.ec 的值为 errc::value_too_largeto_char_result.ptr 的值为 last,并且范围 [first, last) 的内容未指定。

to_chars 可能失败的唯一原因是提供的缓冲区不够大而无法保存结果。

// integer to chars

to_chars_result to_chars(char* first, char* last, char value, int base = 10);
to_chars_result to_chars(char* first, char* last, signed char value, int base = 10);
to_chars_result to_chars(char* first, char* last, unsigned char value, int base = 10);
to_chars_result to_chars(char* first, char* last, short value, int base = 10);
to_chars_result to_chars(char* first, char* last, unsigned short value, int base = 10);
to_chars_result to_chars(char* first, char* last, int value, int base = 10);
to_chars_result to_chars(char* first, char* last, unsigned int value, int base = 10);
to_chars_result to_chars(char* first, char* last, long value, int base = 10);
to_chars_result to_chars(char* first, char* last, unsigned long value, int base = 10);
to_chars_result to_chars(char* first, char* last, long long value, int base = 10);
to_chars_result to_chars(char* first, char* last, unsigned long long value, int base = 10);
to_chars_result to_chars(char* first, char* last, bool value, int base = 10) = delete;

// floating-point to chars

to_chars_result to_chars(char* first, char* last, float value);
to_chars_result to_chars(char* first, char* last, double value);
to_chars_result to_chars(char* first, char* last, long double value);
to_chars_result to_chars(char* first, char* last, float value, chars_format fmt);
to_chars_result to_chars(char* first, char* last, double value, chars_format fmt);
to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt);
to_chars_result to_chars(char* first, char* last, float value, chars_format fmt, int precision);
to_chars_result to_chars(char* first, char* last, double value, chars_format fmt, int precision);
to_chars_result to_chars(char* first, char* last, long double value, chars_format fmt, int precision);

参数

first
指向要填充的缓冲区的开头。

last
指向要填充的缓冲区末尾的下一个字符。

value
要转换的值。 如果 value 为负值,则表示形式以 - 开头。

base
在整数转换中,将 value 转换为字符时要使用的基数。 必须为 2 到 36(含)的数字。 不会有前导零。 范围 10..35(含)中的数字表示为小写字符 a..z

fmt
对于浮点转换,位掩码指定要使用的转换格式,例如科学记数法、固定记数法或十六进制记数法。 请参阅 chars_format 了解详细信息。

精度
在浮点转换中,转换后值的精度位数。

返回值

包含转换结果的 to_chars_result

注解

采用 chars_format 参数的函数将确定转换说明符,就像使用 printf() 一样,如下所示:如果 fmtchars_format::fixed,则转换指示符为 'f';如果 fmtchars_format::scientific,则为 'e';如果 fmtchars_format::hex,则为 'a'(结果中不带前导 0x);如果 fmtchars_format::general,则为 'g'。 指定最短固定记数法仍可能导致较长的输出,因为当值非常大或非常小时,它可能是最短的表示形式。

下表描述了给定不同 fmtprecision 参数组合的转换行为。 术语“最短往返行为”是指写入所需的最少数字,以便使用相应的 from_chars 函数分析表示形式将完全恢复该值。

fmtprecision 组合 输出
两者均未选中 无论固定记数法较短还是科学记数法较短,固定记数法都更胜一筹。
任何采用 fmt 参数的重载都无法模拟此行为。
fmt 指定格式的最短往返行为,例如最短的科学记数法格式。
fmtprecision 使用给定精度,遵循 printf() 样式,而不执行最短往返行为。

示例

#include <charconv>
#include <stdio.h>
#include <system_error>

template <typename T> void TestToChars(const T t)
{
    static_assert(std::is_floating_point_v<T>);
    constexpr bool IsFloat = std::is_same_v<T, float>;

    char buf[100]; // 100 is large enough for double and long double values because the longest possible outputs are "-1.23456735e-36" and "-1.2345678901234567e-100".
    constexpr size_t size = IsFloat ? 15 : 24;
    const std::to_chars_result res = std::to_chars(buf, buf + size, t);  // points to buffer area it can use. Must be char, not wchar_t, etc.

    if (res.ec == std::errc{}) // no error
    {
        // %.*s provides the exact number of characters to output because the output range, [buf, res.ptr), isn't null-terminated
        printf("success: %.*s\n", static_cast<int>(res.ptr - buf), buf);
    }
    else // probably std::errc::value_too_large
    {
        printf("Error: %d\n", static_cast<int>(res.ec));
    }
}

int main()
{
    TestToChars(123.34);
    return 0;
}

from_chars

char 序列转换为整数值或浮点值。

// char to an integer value

from_chars_result from_chars(const char* first, const char* last, char& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, signed char& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, unsigned char& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, short& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, unsigned short& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, int& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, unsigned int& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, long& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, unsigned long& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, long long& value, int base = 10);
from_chars_result from_chars(const char* first, const char* last, unsigned long long& value, int base = 10);

// char to a floating-point value

from_chars_result from_chars(const char* first, const char* last, float& value, chars_format fmt = chars_format::general);
from_chars_result from_chars(const char* first, const char* last, double& value, chars_format fmt = chars_format::general);
from_chars_result from_chars(const char* first, const char* last, long double& value, chars_format fmt = chars_format::general);

参数

first
指向要转换的字符缓冲区的开头。

last
指向要转换的字符缓冲区的最末尾元素的下一个元素。

value
如果转换成功,则包含转换结果。

base
在整数转换中,转换期间要使用的基数。 必须为 2 到 36(含)的数字。

fmt
在浮点转换中,要转换的字符序列的格式。 请参阅 chars_format 了解详细信息。

备注

from_chars() 函数分析字符串 [first, last) 的数字模式,其中 [first, last) 必须是有效范围。

分析字符时,不会忽略空格。 与 strtod() 不同,例如,缓冲区必须以有效的数字表示形式开头。

返回 from_chars_result 结构

如果没有字符与数字模式匹配,则 value 未修改,from_chars_result.ptr 指向 firstfrom_chars_result.ecerrc::invalid_argument

如果只有一些字符与数字模式匹配,则 from_chars_result.ptr 指向与该模式不匹配的第一个字符,或者如果所有字符匹配,则具有 last 参数的值。

如果分析的值不在可按 value 类型表示的范围中,则 value 未修改且 from_chars_result.ecerrc::result_out_of_range

否则,value 在舍入后设置为已分析的值,并且 from_chars_result.ec 等于 errc{}

示例

#include <charconv>
#include <stdio.h>
#include <string_view>
#include <system_error>

double TestFromChars(const std::string_view sv)
{
    const char* const first = sv.data();
    const char* const last = first + sv.size();
    double dbl;

    const std::from_chars_result res = std::from_chars(first, last, dbl);

    if (res.ec == std::errc{}) // no error
    {
        printf("success: %g\n", dbl);
    }
    else
    {
        printf("Error: %d\n", static_cast<int>(res.ec));
    }

    return dbl;
}

int main()
{
    double dbl = TestFromChars("123.34");
    return 0;
}

要求

标头:<charconv>

命名空间: std

需要 /std:c++17 或更高版本。

另请参阅

<charconv>
往返的最短十进制字符串printf() 格式说明符