拡張 lexical_cast
C++で数字文字列<->数値の変換を行うときには専らlexical_castを使っているのですが, 16進数や8進数などに変換できないことに気づきました. そこで,strtolなどの関数を見てみるとbaseと言う引数で 基数を指定できるようになっていたので,これに習ってlexical_castを拡張してみました. 場合によってsetf()するだけなので,拡張と言うほど大げさなものでもないですが.
lexical_castの第二引数には,基数としてstd::ios::dec,std::ios::hex,std::ios::oct を指定することができます.基数を指定した場合,lexical_castは基数にしたがって 数字文字列をそれぞれ10進数,16進数,8進数として変換を行います. 尚,基数を省略した場合は10進数(std::ios::dec)として変換が行われるので, 普段はboost::lexical_castと同じ感覚で使うことができます.
また,第二引数にstd::ios::showbaseを指定した場合には,文字列に応じた変換がなされます. つまり,0xで始まる数字文字列であるならば16進数として,0で始まる数字文字列であるならば 8進数として,それ以外の数字文字列は10進数として変換が行われます.
以下がサンプルプログラム.lexical_cast.h
#include <iostream>
#include <string>
#include "clx/lexical_cast.h"
int main(int argc, char* argv[]) {
std::string s1 = "326";
std::string s2 = "0xf2a";
std::string serr = "nonum";
try {
int a = clx::lexical_cast<int>(s1, std::ios::oct);
int b = clx::lexical_cast<int>(s2, std::ios::showbase);
std::cout << "str " << s1 << ", val " << a << std::endl;
std::cout << "str " << s2 << ", val " << b << std::endl;
int c = clx::lexical_cast<int>(serr);
std::cout << "str " << serr << ", val " << c << std::endl;
}
catch (clx::bad_lexical_cast e) {
std::cerr << "exeption: " << e.what() << std::endl;
std::exit(-1);
}
return 0;
}
Result
str 326, val 214
str 0xf2a, val 3882
exeption: bad lexical cast