如何使用cout打印0x0a而不是0xa?
#include <iostream>
using std::cout;
using std::endl;
using std::hex;
int main()
{
cout << hex << showbase << 10 << endl;
}
答案 0 :(得分:79)
这适用于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;
}
答案 1 :(得分:18)
使用setw
中的setfill和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;
}
就个人而言,iostreams的有状态性质总是让我烦恼。我认为提升格式是一个更好的选择,所以我建议另一个答案。
答案 2 :(得分:7)
如果您想更简单地输出十六进制数字,可以编写如下函数:
更新版本如下;有两种方法可以插入0x
基本指标,脚注详细说明它们之间的差异。原始版本保留在答案的底部,以免给使用它的任何人带来不便。
请注意,更新版本和原始版本可能需要针对字节大小为9位的倍数的系统进行一些定制。
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。
脚注:
此行负责显示基数,可以是以下任一项:
<< "0x"
<< std::showbase
对于尝试将负十六进制数输出为-0x##
而不是<complement of 0x##>
的自定义类型,第一个选项将显示不正确,标记显示在基数之后({{1}而不是在它之前。这很少是一个问题,所以我个人更喜欢这个选项。
如果这是一个问题,那么在使用这些类型时,您可以在输出基数之前检查否定性,然后使用0x-##
(或a custom abs()
that returns an unsigned value,如果您需要能够在abs()
上处理2补码系统上的最负值。
第二个选项会在val
时省略基数,显示(例如,val == 0
,其中int
是32位)int
而不是预期0000000000
。这是因为0x00000000
标记在内部被视为showbase
&n; printf()
修饰符。
如果这是一个问题,您可以检查是否#
,并在适用时进行特殊处理。
根据选择显示基础的选项,需要更改两行。
val == 0
,则<< "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();
}
工作示例:here。
答案 3 :(得分:3)
在 C++20 中,您将能够使用 std::format
来执行此操作:
std::cout << std::format("{:02x}\n", 10);
输出:
0a
在此期间您可以使用 the {fmt} library,std::format
是基于。 {fmt} 还提供了 print
函数,使这变得更加简单和高效 (godbolt):
fmt::print("{:02x}\n", 10);
免责声明:我是 {fmt} 和 C++20 std::format
的作者。
答案 4 :(得分:1)
尝试这个..你只需根据幅度预先设置零。
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(对于一个十六进制数字):
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
答案 5 :(得分:1)
缺少答案的重要一点是,您必须将right
与所有上述标志一起使用:
cout<<"0x"<<hex<<setfill('0')<<setw(2)<<right<<10;
答案 6 :(得分:1)
为了缩短输出十六进制的内容,我制作了一个简单的宏
#define PADHEX(width, val) setfill('0') << setw(width) << std::hex << (unsigned)val
然后
cout << "0x" << PADHEX(2, num) << endl;
答案 7 :(得分:0)
使用自动填充“0”或设置将任意数字打印到十六进制。模板允许任何数据类型(例如uint8_t)
echo 'export PYTHONPATH="/home/myname/pp:$PYTHONPATH"' >> ~/.bash_profile
示例:
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();
答案 8 :(得分:0)
#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;
}