2016-11-17 96 views
1

我們可以用不同的選項改變數據流的行爲:格式自定義類型與ostream的

std::cout << 0xfabadau << '\n'; 
std::cout << std::hex << std::setfill('0') << std::setw(8) << 0xfabadau << '\n'; 

輸出:

16431834 
00fabada 

現在可以說我有一個byte_buffer定製類型:

using byte  = std::uint8_t; 
using byte_buffer = std::vector<byte>; 

std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer) 
{ 
    for (const auto &b : buffer) o << std::hex << int{b}; 
    return o << std::dec; 
} 

Usin克它我不能應用自定義格式::

byte_buffer b { 0xfau, 0xbau, 0xdau, }; 
std::cout << b << '\n'; 
std::cout << std::hex << std::setfill('0') << std::setw(8) << b << '\n'; 

上面的代碼示出了下面的輸出:

fabada 
000000fabada 

std::setfillstd::setw以外的std::ostream &operator <<被影響第一bytebyte_buffer裏面的std::ostream &operator <<因此觀察到的輸出,這是不出乎意料的不是我想要的。我想輸出是:

fabada 
00fabada 

我應該如何才能使byte_buffer表現我想要的方式改變std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer)

回答

1

你可以用一個字節的東西像這樣工作

std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer) 
{ 
    std::uint32_t temp=0; 
    for (const auto &b : buffer) 
    { 
     temp<<=8; 
     temp|=b; 
    } 
    return o << std::hex << temp << std::dec; 
} 

更靈活的方式

std::ostream &operator <<(std::ostream &o, const byte_buffer &buffer) 
{ 
    std::ostringstream ss; 
    for (const auto &b : buffer) 
    { 
     ss<< std::hex << int{b}; 
    } 
    return o << ss.str(); 
} 
+0

這是一個非常有趣的方法:)但它不適用於任意長度的緩衝區(想象一個長度超過4,8,16的byte_buffer) ,666 ...)。 –

+0

是的,它很棘手,但它的工作原理,請參閱更新答案! – quazeeee

1

你總是可以得到的標誌,並利用它們在你的功能,但是你想。例如(只處理這裏的寬度)

int width = o.width(), item_width; 
int fill = o.fill(); 
if (width > 2*buffer.size()) 
    item_width = width - 2*(buffer.size()-1); 
else 
    item_width = 2; 
for (const auto &b : buffer) 
{ 
    o << std::hex << std::setw(item_width) << setfill(fill) << int{b}; 
    item_width = 2; fill = '0'; 
}