web-dev-qa-db-ja.com

coutを使用して0xaの代わりに0x0aを印刷するにはどうすればよいですか?

Coutを使用して0xaの代わりに0x0aを印刷するにはどうすればよいですか?

#include  <iostream>

using std::cout;  
using std::endl;  
using std::hex;

int main()  
{  
    cout << hex << showbase << 10 << endl;  
}
51
Ayrosa

これはGCCで私にとってはうまくいきます:

#include  <iostream>
#include  <iomanip>

using namespace std;

int main()
{
    cout << "0x" << setfill('0') << setw(2) << hex << 10 << endl;
}

Iostreamのフォーマットの癖にうんざりしている場合は、 Boost.Format を試してください。昔ながらのprintfスタイルのフォーマット指定子を使用できますが、タイプセーフです。

#include <iostream>
#include <boost/format.hpp>

int main()
{
    std::cout << boost::format("0x%02x\n") % 10;
}
84
Emile Cormier

setw および setfill from iomanip を使用

#include  <iostream>
#include  <iomanip>

using std::cout;  
using std::endl;  
using std::hex;

int main()
{
    cout << "0x" << std::setfill('0') << std::setw(2) << hex << 10 << endl;
}

個人的に、iostreamのステートフルな性質は常に私を悩ます。ブースト形式はより良いオプションだと思うので、他の答えをお勧めします。

20
Doug T.

16進数を出力する簡単な方法が必要な場合は、次のような関数を作成できます。

更新されたバージョンを以下に示します。 0xベースインジケーターを挿入するには2つの方法があり、それらの違いを詳しく説明した脚注があります。元のバージョンは回答の下部に保存されているため、それを使用していたユーザーに迷惑をかけません。

更新されたバージョンと元のバージョンの両方で、バイトサイズが9ビットの倍数であるシステム用に調整が必要になる場合があることに注意してください。

#include <type_traits> // For integral_constant, is_same.
#include <string>      // For string.
#include <sstream>     // For stringstream.
#include <ios>         // For hex, internal, [optional] showbase.
                       // Note: <ios> is unnecessary if <iostream> is also included.
#include <iomanip>     // For setfill, setw.
#include <climits>     // For CHAR_BIT.

namespace detail {
    constexpr int HEX_DIGIT_BITS = 4;
    //constexpr int HEX_BASE_CHARS = 2; // Optional.  See footnote #2.

    // Replaced CharCheck with a much simpler trait.
    template<typename T> struct is_char
      : std::integral_constant<bool,
                               std::is_same<T, char>::value ||
                               std::is_same<T, signed char>::value ||
                               std::is_same<T, unsigned char>::value> {};
}

template<typename T>
std::string hex_out_s(T val) {
    using namespace detail;

    std::stringstream sformatter;
    sformatter << std::hex
               << std::internal
               << "0x"                                             // See footnote #1.
               << std::setfill('0')
               << std::setw(sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) // See footnote #2.
               << (is_char<T>::value ? static_cast<int>(val) : val);

    return sformatter.str();
}

次のように使用できます。

uint32_t       hexU32 = 0x0f;
int            hexI   = 0x3c;
unsigned short hexUS  = 0x12;

std::cout << "uint32_t:       " << hex_out_s(hexU32) << '\n'
          << "int:            " << hex_out_s(hexI)   << '\n'
          << "unsigned short: " << hex_out_s(hexUS)  << std::endl;

両方のオプションを参照してください(下記の脚注に詳細があります): here

脚注:

  1. この行はベースの表示を担当し、次のいずれかです。

    << "0x"
    << std::showbase
    
    • 最初のオプションは、負の16進数を-0x##ではなく<complement of 0x##>として出力しようとするカスタムタイプに対して不適切に表示され、その前ではなくベースの後に(0x-##として)記号が表示されます。これが問題になることはほとんどないため、個人的にはこのオプションを好みます。

      これが問題である場合、これらのタイプを使用する場合、ベースを出力する前にネガティブをチェックし、abs()(または nsignedを返すカスタムabs())を使用できますvalue 、2の補数システムで最も負の値を処理できるようにする必要がある場合)val

    • 2番目のオプションは、val == 0の表示時にベースを省略します(たとえば、intの場合、intは32ビット)、期待される0000000000ではなく0x00000000。これは、showbaseフラグがprintf()#修飾子のように内部的に処理されるためです。

      これが問題になる場合は、val == 0であるかどうかを確認し、その場合は特別な処理を適用できます。

  2. ベースを表示するために選択したオプションに応じて、2行を変更する必要があります。

    • << "0x"を使用する場合、HEX_BASE_CHARSは不要であり、省略できます。
    • << std::showbaseを使用する場合、setw()に提供される値はこれを考慮する必要があります。

      << std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
      

元のバージョンは次のとおりです。

// Helper structs and constants for hex_out_s().
namespace hex_out_helper {
    constexpr int HEX_DIGIT_BITS = 4; // One hex digit = 4 bits.
    constexpr int HEX_BASE_CHARS = 2; // For the "0x".

    template<typename T> struct CharCheck {
        using type = T;
    };

    template<> struct CharCheck<signed char> {
        using type = char;
    };

    template<> struct CharCheck<unsigned char> {
        using type = char;
    };

    template<typename T> using CharChecker = typename CharCheck<T>::type;
} // namespace hex_out_helper


template<typename T> std::string hex_out_s(T val) {
    using namespace hex_out_helper;

    std::stringstream sformatter;
    sformatter << std::hex
               << std::internal
               << std::showbase
               << std::setfill('0')
               << std::setw((sizeof(T) * CHAR_BIT / HEX_DIGIT_BITS) + HEX_BASE_CHARS)
               << (std::is_same<CharChecker<T>, char>{} ? static_cast<int>(val) : val);
    return sformatter.str();
}

これは次のように使用できます:

uint32_t       hexU32 = 0x0f;
int            hexI   = 0x3c;
unsigned short hexUS  = 0x12;

std::cout << hex_out_s(hexU32) << std::endl;
std::cout << hex_out_s(hexI) << std::endl;
std::cout << "And let's not forget " << hex_out_s(hexUS) << std::endl;

作業例: here

7
Justin Time

答えが欠けている重要なことは、上記のすべてのフラグでrightを使用する必要があるということです。

cout<<"0x"<<hex<<setfill('0')<<setw(2)<<right<<10;
1
lentz

これを試してください。大きさに基づいてゼロを追加するだけです。

cout << hex << "0x" << ((c<16)?"0":"") << (static_cast<unsigned int>(c) & 0xFF) << "h" << endl;

これを簡単に変更して、より大きな数で動作するようにできます。

cout << hex << "0x";
cout << ((c<16)?"0":"") << ((c<256)?"0":"");
cout << (static_cast<unsigned int>(c) & 0xFFF) << "h" << endl;

係数は16(1桁の16進数)です:
16、256、4096、65536、1048576、..
それぞれ
0x10、0x100、0x1000、0x10000、0x100000、..

したがって、このように書くこともできます。

cout << hex << "0x" << ((c<0x10)?"0":"") << ((c<0x100)?"0":"") << ((c<0x1000)?"0":"") << (static_cast<unsigned int>(c) & 0xFFFF) << "h" << endl;

など..:P

1

16進数を出力するために時間を短縮するために、単純なマクロを作成しました

#define PADHEX(width, val) setfill('0') << setw(width) << std::hex << (unsigned)val

それから

cout << "0x" << PADHEX(2, num) << endl;
1
rwhenderson

自動パディング「0」または設定を使用して、16進数に任意の数値を出力します。テンプレートは任意のデータ型を許可します(例:uint8_t)

template<typename T, typename baseT=uint32_t> struct tohex_t {
    T num_;
    uint32_t width_;
    bool showbase_;

    tohex_t(T num, bool showbase = false, uint32_t width = 0) { num_ = num; showbase_ = showbase; width_ = width; }
    friend std::ostream& operator<< (std::ostream& stream, const tohex_t& num) {
        uint32_t w;
        baseT val;

        if (num.showbase_)
            stream << "0x";

        if (num.width_ == 0) {
            w = 0;
            val = static_cast<baseT>(num.num_);
            do { w += 2; val = val >> 8; } while (val > 0);
        }
        else {
            w = num.width_;
        }
        stream << std::hex << std::setfill('0') << std::setw(w) << static_cast<baseT>(num.num_);

        return stream;
    }
};
template<typename T> tohex_t<T> TO_HEX(T const &num, bool showbase = false, uint32_t width = 0) { return tohex_t<T>(num, showbase, width); }

例:

std::stringstream sstr;
uint8_t ch = 91;
sstr << TO_HEX(5) << ',' << TO_HEX(ch) << ',' << TO_HEX('0') << std::endl;
sstr << TO_HEX(1, true, 4) << ',' << TO_HEX(15) << ',' << TO_HEX(-1) << ',';
sstr << TO_HEX(513) << ',' << TO_HEX((1 << 16) + 3, true);
std::cout << sstr.str();

出力:

05,5b,30
0x0001,0f,ffffffff,0201,0x010003
0
Danilo Ramos