- charconv[meta header]
- function template[meta id-type]
- std[meta namespace]
- cpp17[meta cpp]
namespace std {
//整数型用
to_chars_result to_chars(char* first, char* last, /*see below*/ value, int base = 10); // (1)
//精度、フォーマット指定なし
to_chars_result to_chars(char* first, char* last, float value); // (2)
to_chars_result to_chars(char* first, char* last, double value); // (3)
to_chars_result to_chars(char* first, char* last, long double value); // (4)
//精度指定なし
to_chars_result to_chars(char* first, char* last, float value,
chars_format fmt); // (5)
to_chars_result to_chars(char* first, char* last, double value,
chars_format fmt); // (6)
to_chars_result to_chars(char* first, char* last, long double value,
chars_format fmt); // (7)
//精度とフォーマットを指定
to_chars_result to_chars(char* first, char* last, float value,
chars_format fmt, int precision); // (8)
to_chars_result to_chars(char* first, char* last, double value,
chars_format fmt, int precision); // (9)
to_chars_result to_chars(char* first, char* last, long double value,
chars_format fmt, int precision); // (10)
}
与えられた数値(value
)を文字列へ変換し、[fisrt, last)
内へ出力する。
変換に際し、メモリ確保を行わず例外を投げることもない。
C++標準はこれら関数の実装の詳細について何も規定しない。これは、各実装において可能な最も高速なアルゴリズムが選択されることを意図しての事である。
- 全て : 出力範囲
[fisrt, last)
は有効な範囲であること(charのオブジェクトが構築済みであり、連続していること)。 - (1) :
base
は2~36までの値であること。 - (5)~(10) :
fmt
はchars_format
の列挙値のうちの一つであること。
first
-- 変換結果の文字列を出力する範囲の先頭のポインタ。last
-- 変換結果の文字列を出力する範囲の終端の次を指すポインタ。value
-- 文字列へ変換する値。base
-- 整数の出力基数(n進数のn)指定、2進数から36進数まで。fmt
-- 浮動小数点数の出力フォーマット指定、chars_format
のいずれか。precision
-- 浮動小数点数の出力精度(小数点以下の桁数)指定、printf
において%.nf, %.ne
などとしたときのn
にあたる。
-
全て :
value
の値を文字列へ変換し、結果文字列を[fisrt, last)
に書き込む。
出力文字列が[fisrt, last)
に収まらない場合は失敗する。 -
(1) :
base
の値をnとすると、整数値をn進数の文字列へ変換する(value
が負なら-
が先頭に付く)。
10 < nの場合、10~36の値はアルファベットの小文字a~zがあてられる。
桁数を合わせるために左側を0をパディングすること(0埋め)は行われない。 -
(2)(3)(4) : Cロケールで
printf
によって行われたかのように浮動小数点数を文字列へ変換する。
フォーマット指定子は%f,%e
どちらかを出力文字列が最も短くなるように(両者が同じなら%f
が優先)選択する。 -
(5)(6)(7) :
fmt
によって指定されたフォーマット指定子を用いて、Cロケールでprintf
によって行われたかのように浮動小数点数を文字列へ変換する。
出力文字列が最も短くなるように変換される。
chars_format::general
が指定された場合は(2)(3)(4)と同等。 -
(8)(9)(10) :
fmt
とprecision
によって指定されたフォーマット指定子と精度を用いて、Cロケールでprintf
によって行われたかのように浮動小数点数を文字列へ変換する。
出力文字列が最も短くなるようにとは、小数点の前に少なくとも1桁あり、対応するfrom_chars
関数によって値を正確に復元できるような最小の文字数、になることである。
そのような文字列表現が複数ある場合、value
の値との差が最も小さくなる物が選ばれ、それも複数あるときはstd::round_to_nearest
に従った丸めによって一つを選択する。
なお、from_chars
関数によって値を正確に復元できるのは両関数が同じ処理系で提供されているときにのみ保証される。
全てのオーバーロードにおいて、変換に失敗した場合の[fisrt, last)
の状態は未規定。
- 成功した場合
ptr
: 書き込まれた最後の文字の次の位置を指す(一般的なイテレータ範囲におけるendに相当)。ec
:ec == errc{}
- 失敗した場合
ptr
:ptr == last
ec
:ec ==
errc::value_too_large
どちらの場合も*ptr == '\0'
や*(--ptr) == '\0'
は保証されない。すなわち、変換後文字列はnull終端されない。
投げない。
(1)の関数は実装によって全ての整数型(符号付、無し)およびchar
のオーバーロードが提供される。
MSVCでは浮動小数点数→10進文字列変換の実装にRyuというアルゴリズムを利用している。
#include <iostream>
#include <charconv>
int main()
{
char out[50]{};
auto begin = std::begin(out);
auto end = std::end(out);
//(1) 10進数文字列へ変換
if (auto [ptr, ec] = std::to_chars(begin, end, 10); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(1) 2進数文字列へ変換
if (auto [ptr, ec] = std::to_chars(begin, end, 65535, 2); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(1) 36進数文字列へ変換
if (auto [ptr, ec] = std::to_chars(begin, end, 35, 36); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//リウヴィル数
constexpr double l = 0.11000100000000000000000100000000000;
//(3) 精度・フォーマット指定なしの浮動小数点数変換
if (auto [ptr, ec] = std::to_chars(begin, end, l); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(6) 精度指定なしの浮動小数点数変換、指数表記
if (auto [ptr, ec] = std::to_chars(begin, end, l, std::chars_format::scientific); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(6) 精度指定なしの浮動小数点数変換、固定小数表記
if (auto [ptr, ec] = std::to_chars(begin, end, l, std::chars_format::fixed); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(6) 精度指定なしの浮動小数点数変換、16進指数表記
if (auto [ptr, ec] = std::to_chars(begin, end, l, std::chars_format::hex); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(9) 精度指定ありの浮動小数点数変換、指数表記
if (auto [ptr, ec] = std::to_chars(begin, end, l, std::chars_format::scientific, 16); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(9) 精度指定ありの浮動小数点数変換、固定小数表記
if (auto [ptr, ec] = std::to_chars(begin, end, l, std::chars_format::fixed, 16); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
//(9) 精度指定ありの浮動小数点数変換、16進指数表記
if (auto [ptr, ec] = std::to_chars(begin, end, l, std::chars_format::hex, 16); ec == std::errc{}) {
std::cout << std::string_view(begin, ptr - begin) << std::endl;
}
else {
std::cout << "conversion failed." << std::endl;
}
}
- std::to_chars[color ff0000]
- std::string_view[link /reference/string_view/basic_string_view.md]
10
1111111111111111
z
0.110001
1.10001e-01
0.110001
1.c29068986fcdfp-4
conversion failed.
conversion failed.
1.c29068986fcdf000p-4
精度指定した16進指数表記以外の浮動小数点数変換に失敗するのはMSVC(VS2019 preview4.1)のバグと思われる。
- C++17
- Clang: 7.0(整数のみ)
- GCC: 8.0(整数のみ)
- Visual C++: 2017 update 7(整数のみ), update 9(full support)