These search terms have been highlighted:[trick]
2009-06-28
シリアル通信のプログラムなどでは,多くの場合 unsigned char の配列にデータを保存する.このようなデータを16進数で標準出力に表示する場合, operator<< をオーバーロードすると便利だ.しかし,単純に unsigned char* に対してオーバーロードすると,オリジナルの (iostream で宣言されているのと) コンフリクトする.以下では,既にある operator<< と整合性を取りつつ,任意に書式設定する方法について解説する.
アイディア †
基本的なアイディアは,
- 出力対象の変数 (上の例では unsigned char*) を含む構造体を定義し,コンストラクタで出力対象の変数を代入できるようにする
- operator<< を定義した構造体に対してオーバーロードする
というもの.ここで定義する構造体のコンストラクタに,書式設定のパラメタを持たせることもできる.
サンプル †
次のプログラムでは,unsigned char* の変数を含む構造体 echo_uschar を定義し,operator<< を echo_uschar に対してオーバーロードしている.
#include <iomanip>
using namespace std;
struct echo_uschar
{
const unsigned char *s;
int n;
const char *delim;
echo_uschar(const unsigned char *_s,int _n,const char *_delim=" ")
: s(_s), n(_n), delim(_delim) {};
};
ostream& operator<< (ostream &lhs, const echo_uschar &rhs)
{
for (int i(0);i<rhs.n;++i)
lhs<<rhs.delim<<setw(2)<<setfill('0')<<hex<<static_cast<int>(rhs.s[i])<<dec;
return lhs;
};
int main(int argc,char**argv)
{
unsigned char data[]= {0x01,0x12,0x33,0x28,0x00};
const int N= sizeof(data)/sizeof(data[0]);
cout<<"data= "<<echo_uschar(data,N)<<endl;
return 0;
}
出力結果:
data= 01 12 33 28 00
main で
cout<<"data= "<<echo_uschar(data,N,"-")<<endl;
とすれば,-で区切れる.
同じ変数型に対して異なる書式を持たせた operator<< を複数作りたい場合は,このメソッドがベストだと思います.