2014-04-08 44 views
1

我有下面的代碼片段打印一個整數的十六進制值,爲什麼COUT <<十六進制的語句,使其餘的打印十六進制格式只

int i=10; 
cout<<hex<<i<<endl; 

和打印的10 a在控制檯上的十六進制值很好,

但下一行,我需要打印另一個變量的十進制值,如

int j=11; 
    cout<<j<<endl; 

,但它也打印的11進制值,b,和如果我用cout<<dec<<j<<endl;它打印十進制值。

另外我注意到,如果之前使用cout<<hex,所有cout都打印變量的十六進制值。

所以我的問題是它的正常行爲?如果我之前使用過<<hex一次,我需要使用<<dec嗎?

+2

雅,我相信你要做'<< dec'或'<< hex'如果你想將其切換。如果我沒有記錯的話,你正在做的是設置一個標誌以十六進制或十進制打印出來,並且它將保持該標誌直到它被設置爲別的東西。 –

+0

是的,你必須重置它爲'std :: dec'(技術上清除'std :: ios_base :: basefield'位掩碼,它仍然會爲std :: ios_base :: hex設置位。 – 0x499602D2

回答

6

是的,你必須按順序使用deccout十進制值,因爲hex是一個「粘」機械手(如順便說許多其它操縱) - 它將停留直到被更改。

1

cout是一個全球性的。在操縱器中移動會改變該全局的狀態。考慮到你可以將操縱器鏈接在一起,cout的實例永遠不會知道何時「解除」它。所以,它仍然存在。

1

你可能會寫自己的手,克服了「粘性」行爲:

#include <iostream> 
#include <iomanip> 
#include <limits> 

// Hex 
// ============================================================================ 

template <typename T> 
struct Hex 
{ 
    enum { Width = (std::numeric_limits<T>::digits + 1)/4 }; 
    const T& value; 
    const int width; 

    Hex(const T& value, int width = Width) 
    : value(value), width(width) 
    {} 

    void write(std::ostream& stream) const { 
     if(std::numeric_limits<T>::radix != 2) stream << value; 
     else { 
      std::ios_base::fmtflags flags = stream.setf(
       std::ios_base::hex, std::ios_base::basefield); 
      char fill = stream.fill('0'); 
      stream << "0x" << std::setw(width) << value; 
      stream.fill(fill); 
      stream.setf(flags, std::ios_base::basefield); 
     } 
    } 
}; 

template <typename T> 
inline Hex<T> hex(const T& value, int width = Hex<T>::Width) { 
    return Hex<T>(value, width); 
} 

template <typename T> 
inline std::ostream& operator << (std::ostream& stream, const Hex<T>& value) { 
    value.write(stream); 
    return stream; 
} 


int main() 
{ 
    unsigned short i = 0xa; 
    std::cout << hex(i) << " == " << i << '\n'; 
    return 0; 
}