Masato's IT Library

Microsoftの製品・サービスを中心に,色々と書いていきたいと思います

C++で浮動小数点型を書式指定してstd::string型に変換する方法(std::_Floating_to_string)

数値から文字列への変換

C++でプログラムを書いていると,ログ出力などで数値型から文字列に変換したいということがよくあります.

minus9d.hatenablog.com

C++では,例えば,12345という数値をstd::string型の文字列に変換するには

std::to_string(12345)

とするだけです.お手軽.

ただ,上の記事でもあるように,C時代のfprintfのように,C++の標準ライブラリを用いた浮動小数点型への詳細な書式指定をした数値から文字列への変換は出来ないとされていました.

そのため,Cみたいにfprintf_s()使ってchar[]な文字列にしてからstringに変換するのを書くのもC++的になんか野暮ったいなあと思い

double doubleNum = 3.1415926535;
int digits = 3;

std::ostringstream oss;
oss << std::fixed << std::setprecision(digits) << doubleNum;
std::string stringNum = oss.str();
// stringNumは "3.141" になる

みたいに書いていました.

ところが,Visual Studio 2017(v15.5.4)で何気なくいつも通りstd::to_stringなどと打っていたら,
intellisenseが何やら気になるものをto_stringの下に表示しているではありませんか

f:id:mst8000:20180125150309p:plain

なにこれ

検索してもまあ情報が出てきません.
const char *_Fmtが何者なのかもわからないので,とりあえず右クリックして定義を表示してみます.

f:id:mst8000:20180125151558p:plain

なるほど,const char *_FmtにはCの書式指定文字列を入れればいいのね, _Ty _Val浮動小数点型の値を渡してあげればいいみたい.

で,ここで少し気になってstd::to_stringの定義をのぞいてみると...

f:id:mst8000:20180125154339p:plain

あった
どうやらto_stringが内部的に使用しているようです.

ということで,

まとめ

std::_Floating_to_string

namespace std {
  string _Floating_to_string(char* fmt, T val)
}

Tはfloat, double, const doubleなどの浮動小数点型

概要

浮動小数点型の数値valfmtの書式でstring型の文字列に変換する.

戻り値

各数値型に対して、sprintf_s(buf, len, fmt, val)によって生成された文字列のstringオブジェクトを返す.
バッファサイズはフォーマットと渡された値から適切に計算される.

double doubleNum = 3.1415926535;
std::cout << std::_Floating_to_string("%.3f", doubleNum) << std::endl;
std::cout << std::_Floating_to_string("%10.5f", doubleNum) << std::endl;

出力

3.141
   3.14159

バージョン

  • 言語  C++17?
  • 処理系 Visual C++ 2017 (15.5.4)で確認

Ubuntu 16.04 (Bash on Ubuntu on Windows)でaptを高速化する

WSL(Windows Subsystem for Linux)のUbuntu 16.04では,aptで参照する既定のリポジトリhttp://archive.ubuntu.com/ubuntu/ であるため非常に遅いです.

そこで,日本国内から高速でアクセスできるミラーであるIIJjaistリポジトリを追加します.

listファイルの追加

次のファイルを作成します.
ほかにお好きなサーバがあれば同様に追加します.

/etc/apt/sources.list.d/iij.list
deb http://ftp.iij.ad.jp/pub/linux/ubuntu/archive/ xenial main restricted universe multiverse
deb http://ftp.iij.ad.jp/pub/linux/ubuntu/archive/ xenial-updates main restricted universe multiverse
deb http://ftp.iij.ad.jp/pub/linux/ubuntu/archive/ xenial-backports main restricted universe multiverse
deb http://ftp.iij.ad.jp/pub/linux/ubuntu/archive/ xenial-security main restricted universe multiverse
/etc/apt/sources.list.d/jaist.list
deb http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ xenial main restricted universe multiverse
deb http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ xenial-updates main restricted universe multiverse
deb http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ xenial-backports main restricted universe multiverse
deb http://ftp.jaist.ac.jp/pub/Linux/ubuntu/ xenial-security main restricted universe multiverse

archive.ubuntu.comの無効化

続いて,元々設定されていた http://archive.ubuntu.com/ubuntu/ を参照しないようにします

/etc/apt/sources.list
deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse
deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse

のsecurity以外の行を次のようにコメントアウトします

#deb http://archive.ubuntu.com/ubuntu/ xenial main restricted universe multiverse
#deb http://archive.ubuntu.com/ubuntu/ xenial-updates main restricted universe multiverse
deb http://security.ubuntu.com/ubuntu/ xenial-security main restricted universe multiverse

以上です.
あとは通常通り sudo apt update を実行すると追加したリポジトリを参照するようになります.

よいWindows Subsystem for Linux(WSL)ライフを!

Bash on Ubuntu on Windows (WSL)のシェル配色テーマ変更

既定の配色だとカレントディレクトリetc. が大層見にくいので,こちらの記事に沿って変更

www.hanselman.com

f:id:mst8000:20170731150948p:plain:w600

配色テーマのダウンロード

wgetここから dircolors.ansi-universal を取得
このとき,保存ファイル名を .dircolors にして ~/に保存します

github.com

wget -O .dircolors https://raw.githubusercontent.com/seebi/dircolors-solarized/master/dircolors.ansi-universal

配色テーマの適用

.bashrc を再読み込みして適用します

source ~/.bashrc

f:id:mst8000:20170731154228p:plain:w600

プロンプト文字列のカレントディレクトリの色を変更

ついでに,カレントディレクトリの色も青だと見づらいので,シアンにでも変更しておこうと思います

.bashrc の60行目付近

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[01;34m\]\w\[\033[00m\]\$ '
else

if [ "$color_prompt" = yes ]; then
    PS1='${debian_chroot:+($debian_chroot)}\[\033[01;32m\]\u@\h\[\033[00m\]:\[\033[00;36m\]\w\[\033[00m\]\$ '
else

に変更して,.bashrc を再読み込みします

source ~/.bashrc

ずいぶんと見やすくなりましたね

f:id:mst8000:20170731155327p:plain:w600

よいWindows Subsystem for Linux(WSL)ライフを!