C++のマニピュレータ
マニピュレータとは
C++のストリームの形式を変えるための関数などのことをいいます。
マニピュレータはいくつかのヘッダに分かれています。
確認できただけではios, iomanipヘッダに分かれています。
一覧
名前空間のstdは省略して記します。
名前 | ヘッダ | no-があるか | 動作 |
---|---|---|---|
resetiosflags | <iomanip> | No | 引数で指定したフラグをリセットする(reset ios flags) |
setiosflags | <iomanip> | No | 引数で指定したフラグをセットする |
setbase | <iomanip> | No | 基数を設定する。8, 10, 16以外の値が来た場合フラグはリセットされる |
setfill | <iomanip> | No | 埋める文字を指定する |
setw | <iomanip> | No | フィールドの幅を指定する |
put_money | <iomanip> | No | 金額書式で出力する (get_moneyもある。C++11以降) |
put_time | <iomanip> | No | 日時書式で出力する (get_timeもある。C++11以降) |
dec | <ios> | No | 10進数で表示する |
oct | <ios> | No | 8進数で表示する |
hex | <ios> | No | 16進数で表示する |
boolalpha | <ios> | Yes | bool値をtrue, falseで表示させる |
showbase | <ios> | Yes | 基数を示すプレフィックス(0xなど)を表示させる |
showpoint | <ios> | Yes | 浮動小数点を表示させる |
showpos | <ios> | Yes | 正符号を表示させる(1を+1) |
skipws | <ios> | Yes | 入力時に空白を読み飛ばす |
uppercase | <ios> | Yes | 大文字で表示させる(std::hexなどと一緒に使われる) |
unitbuf | <ios> | Yes | 出力の都度吐き出す |
internal | <ios> | No | 両端揃え |
left | <ios> | No | 左揃え |
right | <ios> | No | 右揃え |
fixed | <ios> | No | 小数表記で出力(1.2とか) |
scientific | <ios> | No | 指数表記で出力 |
hexfloat | <ios> | No | 16進数の小数表記(C++11以降) |
defaultfloat | <ios> | No | 小数表記と指数表記の自動切り替え(C++11以降) |
実行してみた
manip.cpp
#include <iomanip>
#include <iostream>
int main() {
std::cout << "resetiosflags(floatfield): " << std::resetiosflags(std::ios_base::floatfield) << std::endl;
std::cout << "setiosflags(scientific): " << std::setiosflags(std::ios_base::scientific) << std::endl;
std::cout << "setbase(8): " << std::setbase(8) << 0123 << ", " << 123 << ", " << 0x123 << std::endl;
std::cout << "setw(5): " << std::setw(5) << 123 << std::endl;
std::cout << "setfill('0'): " << std::setw(5) << std::setfill('0') << 123 << std::endl;
#if __cplusplus >= 201103L
std::cout.imbue(std::locale("en_US.utf8"));
std::cout << "put_money(300): " << std::put_money(300.) << std::endl;
std::cout << "put_money(300, true): " << std::put_money(300., true) << std::endl;
std::cout.imbue(std::locale("ja_JP.utf8"));
auto tt = std::time(nullptr);
struct tm t = {};
::localtime_r(&tt, &t);
std::cout << "put_time(300): " << std::put_time(&t, "%EY(%Y)/%m/%d %H:%M:%S") << std::endl;
#else
std::cout << "put_money and put_time is not supported in this version." << std::endl;
#endif
std::cout << "dec: " << std::dec << 0123 << ", " << 123 << ", " << 0x123 << std::endl;
std::cout << "oct: " << std::oct << 0123 << ", " << 123 << ", " << 0x123 << std::endl;
std::cout << "hex: " << std::hex << 0123 << ", " << 123 << ", " << 0x123 << std::endl;
std::cout << "boolalpha: " << std::boolalpha << true << std::endl;
std::cout << "noboolalpha: " << std::noboolalpha << true << std::endl;
std::cout << "showbase(hex): " << std::hex << std::showbase << 0x123 << std::endl;
std::cout << "noshowbase(hex): " << std::hex << std::noshowbase << 0x123 << std::endl;
std::cout << "showpoint: " << std::showpoint << 1.0 << ", " << 1.2 << std::endl;
std::cout << "noshowpoint: " << std::noshowpoint << 1.0 << ", " << 1.2 << std::endl;
std::cout << "uppercase: " << std::uppercase << std::hex << 0xbeef << std::endl;
std::cout << "nouppercase: " << std::nouppercase << std::hex << 0xbeef << std::endl;
std::cout << std::setfill('-');
std::cout << "internal(setw(20)): " << std::setw(20) << std::internal << "abcd" << std::endl;
std::cout << "left(setw(20)): " << std::setw(20) << std::left << "abcd" << std::endl;
std::cout << "right(setw(20)): " << std::setw(20) << std::right << "abcd" << std::endl;
std::cout << "fixed: " << std::fixed << 1.2 << std::endl;
std::cout << "scientific: " << std::scientific << 1.2 << std::endl;
#if __cplusplus >= 201103L
std::cout << "hexfloat: " << std::hexfloat << 1.2 << std::endl;
std::cout << "defaultfloat: " << std::defaultfloat << 1.2 << ", " << 120000000.0 << std::endl;
#else
std::cout << "hexfloat and defaultfloat is not supported in this version." << std::endl;
#endif
}
clang++ -std=c++11 manip.cpp
実行結果
resetiosflags(floatfield):
setiosflags(scientific):
setbase(8): 123, 173, 443
setw(5): 173
setfill('0'): 00173
put_money(300): 3.00
put_money(300, true): 03.00
put_time(300): 平成30年(2018)/06/12 21:07:42
dec: 83, 123, 291
oct: 123, 173, 443
hex: 53, 7b, 123
boolalpha: true
noboolalpha: 1
showbase(hex): 0x123
noshowbase(hex): 123
showpoint: 1.000000e+00, 1.200000e+00
noshowpoint: 1.000000e+00, 1.200000e+00
uppercase: B,EEF
nouppercase: b,eef
internal(setw(20)): ----------------abcd
left(setw(20)): abcd----------------
right(setw(20)): ----------------abcd
fixed: 1.200000
scientific: 1.200000e+00
hexfloat: 0x1.3333333333333p+0
defaultfloat: 1.2, 1.2e+08
感想
C++でstd::stringstreamでsprintfみたいなことをしようとするとちょっとめんどくさいけど、put_time
とかはなんとなく便利そうだなと感じました。
一応やろうと思えばsprintf相当のことはストリームでもできそうです。
環境
Linux Mint 18.3(amd64)
$ clang++ --version
clang version 5.0.0-3~16.04.1 (tags/RELEASE_500/final)
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/local/bin