[ C++で開発 ]
文字列で表現された数値を、組み込み型のintなどのインスタンスに変換したり、逆にint型などのインスタンスを文字列に変換したりとした処理をC++で記述するのは意外と面倒です。使用するライブラリによって書き方がいくつかあります。
型安全性(実行時エラーよりコンパイルエラー)、テンプレートによるラッピング、バッファ管理のラッピング、記述の簡潔さを考慮すると、3.の方法がもっとも扱いやすいのですが、基数(16進数等)を指定することができないという制約があります。
まず、文字列から整数に変換するために使用するstrtol系の関数は以下となります。
JIS X 3010 プログラム言語C 7.20.1.4より抜粋
#include <stdlib.h>
関数名 | 概要 | シグニチャ |
---|---|---|
strtol | nptrが指す文字列の最初の部分をlong int型に変換する |
long int strtol( const char * restrict nptr, char ** restrict endptr, int base); |
strtoll | nptrが指す文字列の最初の部分をlong long int型に変換する |
long long int strtoll( const char * restrict nptr, char ** restrict endptr, int base); |
strtoul | nptrが指す文字列の最初の部分をunsigned long int型に変換する |
unsigned long int strtol( const char * restrict nptr, char ** restrict endptr, int base); |
strtoull | nptrが指す文字列の最初の部分をunsigned long long int型に変換する |
unsigned long long int strtol( const char * restrict nptr, char ** restrict endptr, int base); |
整数を文字列に変換するsnprintf関数は以下となります。
JIS X 3010 プログラム言語C 7.19.6.5より抜粋
#include <stdio.h>
関数名 | 概要 | シグニチャ |
---|---|---|
snprintf | formatの書式にもとづき変換した出力をsの指す配列へ書き込む。n-1番目より後の出力文字は捨てられる。 |
int snprintf( char * restrict s, size_t n, const char * restrict format, ...); |
ここでは、文字列から数値へ変換する関数、数値から文字列へ変換する関数のインタフェースをC++流に定義し、上記の各実装方法で実装します。
namespace stringutil { template<typename T> T string2binary(const std::string& text, int base); template<typename T> std::string binary2string(T value, int base); }
Tには、数値型のいずれかが合致します。
まず、2.の方法で基数を含めた変換を実現する方法を実装してみます。
iostreamの入出力先を文字列に変換可能なistringstream/ostringstreamとしたものです。
#include <sstream> #include <string> #include <cassert> namespace stringutil { template<typename T> T string2binary(const std::string& text, int base) { assert(base == 8 || base == 10 || base == 16); std::istringstream is(text); T value; switch (base) { case 8: is >> std::oct >> value; break; case 10: is >> value; break; case 16: is >> std::hex >> value; break; default: ; } return value; } } |
#include <sstream> #include <string> #include <cassert> namespace stringutil { template<typename T> std::string binary2string(T value, int base) { assert(base == 8 || base == 10 || base == 16); std::ostringstream os; switch (base) { case 8: if (value < 0) { os << '-'; value *= -1; } os << std::oct; break; case 10: os << std::dec; break; case 16: if (value < 0) { os << '-'; value *= -1; } os << std::hex; break; } os << value; return os.str(); } } |
次に、3.の方法で基数を含めた変換を実現する方法を実装してみます。