coutを使用して0xaの代わりに0x0aを印刷するにはどうすればよいですか?
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << hex << showbase << 10 << endl;
}
これはGCCで私のために働きます:
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
cout << "0x" << setfill('0') << setw(2) << right << hex << 10 << endl;
}
iostreamのフォーマットの癖にうんざりしている場合は、Boost.Formatを試してみてください。古き良きprintfスタイルのフォーマット指定子を使用できますが、タイプセーフです。
#include <iostream>
#include <boost/format.hpp>
int main()
{
std::cout << boost::format("0x%02x\n") % 10;
}
更新(2019)
C++20に受け入れられている{fmt}ライブラリを確認してください。ベンチマークは、Boost.Formatよりも高速であることを示しています。
#if __has_include(<format>)
#include <format>
using std::format;
#else
#include <fmt/format.h>
using fmt::format;
#endif
std::cout << format("{:#04x}\n", 10);
#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のステートフルな性質は常に私を悩ませます。ブースト形式の方が良いと思うので、別の答えをお勧めします。
16進数を出力する簡単な方法を作成したい場合は、次のような関数を作成できます。
更新されたバージョンを以下に示します。ベースインジケーターを挿入する方法は2つあり、0x
脚注でそれらの違いを詳しく説明しています。元のバージョンは、それを使用していた人に迷惑をかけないように、回答の下部に保持されます。
更新されたバージョンと元のバージョンの両方で、バイトサイズが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;
両方のオプション(以下の脚注で詳しく説明されています)をライブで参照してください:ここ。
脚注:
この行はベースを表示する役割を果たし、次のいずれかになります。
<< "0x"
<< std::showbase
-0x##
最初のオプションは、としてではなく負の16進数を出力しようとするカスタムタイプでは不適切に表示さ<complement of 0x##>
れ、記号はベース0x-##
の前ではなくベースの後に(as)で表示されます。これが問題になることはめったにないので、私は個人的にこのオプションを好みます。
これが問題である場合、これらのタイプを使用するときは、ベースを出力する前に負の値をチェックしてから、abs()
(または2の補数で最も負の値を処理できる必要がある場合は符号なしの値を返すカスタムabs()
)を使用できます。補体系)val
。
2番目のオプションは、期待されるの代わりに表示するときにベースを省略しますval == 0
(たとえば、の場合int
、int
は32ビットです)。これは、フラグが内部的にの修飾子のように扱われるためです。0000000000
0x00000000
showbase
printf()
#
これが問題である場合は、かどうかを確認し、問題がval == 0
発生した場合は特別な処理を適用できます。
ベースを表示するために選択したオプションに応じて、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;
実例:ここ。
std::format
C ++ 20では、これを行うために使用できるようになります。
std::cout << std::format("{:02x}\n", 10);
出力:
0a
それまでの間、に基づいて{fmt}ライブラリを使用できます。std::format
{fmt}は、print
これをさらに簡単かつ効率的にする関数も提供します(godbolt)。
fmt::print("{:02x}\n", 10);
免責事項:私は{fmt}とC++20の作者ですstd::format
。
right
答えが欠落している重要なことは、上記のすべてのフラグで使用する必要があるということです。
cout<<"0x"<<hex<<setfill('0')<<setw(2)<<right<<10;
これを試してください..マグニチュードに基づいてゼロを追加するだけです。
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
16進数を出力するための時間を短縮するために、単純なマクロを作成しました
#define PADHEX(width, val) setfill('0') << setw(width) << std::hex << (unsigned)val
それから
cout << "0x" << PADHEX(2, num) << endl;
自動パディング「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
#include <iostream>
#include <iomanip>
using namespace std;
int main()
{
/*This should print out 0x0a. The internal adjustment pads the width with the fill character*/
cout << hex << showbase << internal << setfill('0') << setw(4) << 10 << endl;
}