2013-07-17 56 views
0

格式化我經常做這樣的事情:C++插入到流與十六進制

uint8_t c=some_value; 
std::cout << std::setfill('0') << std::setw(2); 
std::cout << std::hex << int(c); 
std::cout << std::setfill(' '); 

(特別是反傾銷的同時調試信息)。那豈不是不錯的東西manipulatorish我可以把在這樣的流:

的std ::法院< < 「C值:0X」 < < HEXB(C)< < '\ n';

那會做所有這些?有誰知道這是怎麼做到的嗎?

我已經得到這個工作,但希望能有一個簡單的方法:

#include <iostream> 
#include <iomanip> 
class hexcdumper{ 
public: 
    hexcdumper(uint8_t c):c(c){}; 
    std::ostream& 
    operator()(std::ostream& os) const 
    { 
     // set fill and width and save the previous versions to be restored later 
     char fill=os.fill('0'); 
     std::streamsize ss=os.width(2); 

     // save the format flags so we can restore them after setting std::hex 
     std::ios::fmtflags ff=os.flags(); 

     // output the character with hex formatting 
     os << std::hex << int(c); 

     // now restore the fill, width and flags 
     os.fill(fill); 
     os.width(ss); 
     os.flags(ff); 
     return os; 
    } 
private: 
    uint8_t c; 
}; 

hexcdumper 
hexb(uint8_t c) 
{ 
    // dump a hex byte with width 2 and a fill character of '0' 
    return(hexcdumper(c)); 
} 

std::ostream& operator<<(std::ostream& os, const hexcdumper& hcd) 
{  
    return(hcd(os)); 
} 

當我這樣做:

std::cout << "0x" << hexb(14) << '\n'; 
  1. HEXB(三)被調用和返回hexcdumper的構造函數保存c
  2. 重載運算符< <用於hexcdumper調用 hexcdumper :: operator ()傳遞流
  3. hexcdumper的運營商()做所有的魔法爲我們
  4. hexcdumper後::運算符()返回時,重載操作符< < 收益從hexcdumper ::運算符的流()等等鏈接作品。

在輸出時,我看到:

0x0e 

有沒有一種簡單的方法來做到這一點?

帕特里克

+0

您認爲您的解決方案有什麼問題?對我來說看起來不錯,如果它做到了你想要的。 **優雅**已過時! –

回答

0

爲此,您可以直接在流管:

std::cout << "Hex = 0x" << hex << 14 << ", decimal = #" << dec << 14 << endl; 

輸出:

Hex = 0xe, decimal = #14 
+0

@帕特里克在他的問題中說盡可能多的 – mocj

+0

這是真的,但沒有適當地設置填充或寬度,也沒有在沒有很多冗長的情況下恢復它們。問題在於如何避免重複冗長。而不是你的0xe,我更喜歡0x0e,或者如果我用字符串流來輸出3,7和14的字節,我更喜歡03070e到37e,這會令人困惑和可以說是錯誤的。到目前爲止我已經提出了這個解決方案,它也適用於字符串流。 – Patrick

0

正如一個跟進,這確實爲任意寬度相同這一點,並且對於二進制輸出也是如此,例如,假定下面的文件名爲hexbinfmt.h,以下內容:

#include <hexbinfmt.h> 

int 
main() 
{ 
    unsigned long long ll=0x7589347dfdf7834; 
    std::cout << "hexb(ll): 0x" << hexb(ll) << ", bin(ll): " << bin(ll) << '\n'; 
    uint8_t u8t=0xce; 
    std::cout << "hexb(u8t): 0x" << hexb(u8t) << ", bin(u8t): " << bin(u8t) << '\n'; 
} 

輸出:

hexb(ll): 0x07589347dfdf7834, bin(ll): 0000011101011000100100110100011111011111110111110111100000110100 
hexb(u8t): 0xce, bin(u8t): 11001110 

你能幫我找到做同樣的事情的一個簡單的方法?

#ifndef HEXBINFMT_H 
#define HEXBINFMT_H 
#include <iostream> 
#include <iomanip> 

template<typename T> 
class hexcdumper{ 
public: 
    hexcdumper(T c):c(c){}; 
    std::ostream& 
    operator()(std::ostream& os) const 
    { 
    // set fill and width and save the previous ones to be restored later 
    char fill=os.fill('0'); 

    std::streamsize ss=os.width(sizeof(T)*2); 

    // get a copy of the format flags to be restored after setting std::hex 
    std::ios::fmtflags ff=os.flags(); 

    // put the character out as hex 
    if(sizeof(T)==1){ 
     os << std::hex << int(c); 
    }else{ 
     os << std::hex << c; 
    } 

    // restore everything 
    os.fill(fill); 
    os.width(ss); 
    os.flags(ff); 
    return os; 
    } 
private: 
    T c; 
}; 

template<typename T> 
hexcdumper<T> 
hexb(T c) 
{ 
    return(hexcdumper<T>(c)); 
} 

template<typename T> 
std::ostream& operator<<(std::ostream& os, const hexcdumper<T>& hcd) 
{ 
    return(hcd(os)); 
} 

template<typename T> 
class bincdumper{ 
public: 
    bincdumper(T c):c(c){}; 
    std::ostream& 
    operator()(std::ostream& os) const 
    { 
    T mask=1; 
    mask <<= (sizeof(T)*8)-1; 

    for(size_t i=0;i<sizeof(T)*8;i++){ 
     if(c&mask){ 
     os<<'1'; 
     }else{ 
     os<<'0'; 
     } 
     mask>>=1; 
    } 
    return os; 
    } 
private: 
    T c; 
}; 

template<typename T> 
bincdumper<T> 
bin(T c) 
{ 
    return(bincdumper<T>(c)); 
} 

template<typename T> 
std::ostream& operator<<(std::ostream& os, const bincdumper<T>& bcd) 
{ 
    return(bcd(os)); 
} 
#endif