どうも、char や unsigned char を食わせるのが良くないらしい。
数値ではなく文字扱いされているという事のようだ。
static_cast で short や int に直してやると大丈夫だった。
sstest2.cpp
#include <iostream>
#include <sstream>
#include <iomanip>
int main(int argc, char * argv[])
{
unsigned char x[] = {0x01, 0x23, 0x45, 0x67};
std::stringstream ss;
ss << std::setfill('0') << std::hex;
for (int i = 0; i < sizeof(x); i++) {
ss << std::setw(2);
ss << static_cast<int>(x[i]);
}
std::cout << ss.str() << std::endl;
return 0;
}
結果
$ g++ sstest2.cpp && ./a
01234567
差分
$ diff sstest{,2}.cpp
12c12
< ss << x[i];
---
> ss << static_cast<int>(x[i]);
static_cast を使うとどうも野暮ったいので暗黙の型変換を使ったほうがコンパクトで読み易いだろうか?
$ diff sstest{,3}.cpp
12c12
< ss << x[i];
---
> ss << 0 + x[i];
$ diff sstest{2,3}.cpp
12c12
< ss << static_cast<int>(x[i]);
---
> ss << 0 + x[i];
あと、
std::setfill() と std::hex はあらかじめ設定しておけば、以降の入力に対して有効なようだが、
std::setw() は各入力毎に必要な模様。