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はCLX C++ Librariesからダウンロードして下さい.
#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