C++ 使用std::cout打印零填充十六进制
假设我有一个dword,我想用十六进制和std::cout输出,左pad用零输出,所以0xabcd将显示为0x0000abcd。看起来你必须这样做:C++ 使用std::cout打印零填充十六进制,c++,printf,iostream,cout,C++,Printf,Iostream,Cout,假设我有一个dword,我想用十六进制和std::cout输出,左pad用零输出,所以0xabcd将显示为0x0000abcd。看起来你必须这样做: uint32_t my_int = 0xabcd; std::cout << "0x" << std::hex << std::setw(8) << std::setfill('0') << my_int << std::endl; uint32\u t my\u
uint32_t my_int = 0xabcd;
std::cout << "0x" << std::hex << std::setw(8) << std::setfill('0')
<< my_int << std::endl;
uint32\u t my\u int=0xabcd;
STD::CUT> P>我的C++是生锈的,但是使用Boost格式化: < P>我想你可以写一个“流机械手”。如果您有多个十六进制数要以这种格式打印,这将非常有用。这显然不是一个理想的解决方案,但使用包装器类型,您可以创建自己的“格式标志”来切换它。有关更多信息,请参阅
#include <iostream>
#include <iomanip>
static int const index = std::ios_base::xalloc();
std::ostream& hexify(std::ostream& stream) {
stream.iword(index) = 1;
return stream;
}
std::ostream& nohexify(std::ostream& stream) {
stream.iword(index) = 0;
return stream;
}
struct WrapperType {
uint32_t _m;
public:
WrapperType(uint32_t m) : _m(m)
{
}
uint32_t getm() const
{
return _m;
}
};
std::ostream& operator<< (std::ostream& os, const WrapperType& t) {
if (os.iword(index))
return os << "0x" << std::hex << std::setw(8) << std::setfill('0') << t.getm();
else
return os << t.getm();
}
int main()
{
WrapperType my_int{0xabcd};
std::cout << hexify << my_int << my_int;
std::cout << nohexify << my_int;
}
#包括
#包括
静态int const index=std::ios_base::xalloc();
标准::ostream&hexify(标准::ostream&stream){
流.iword(索引)=1;
回流;
}
标准::ostream和nohexify(标准::ostream和stream){
流.iword(索引)=0;
回流;
}
结构包装器类型{
uint32\u t\m;
公众:
包装器类型(uint32\u t m):\u m(m)
{
}
uint32\u t getm()常量
{
返回m;
}
};
std::ostream&operator我不会更改流的(全局)标志,只是一个操纵器:
#include <iostream>
#include <iomanip>
#include <limits>
template <typename T>
struct Hex
{
// C++11:
// static constexpr int Width = (std::numeric_limits<T>::digits + 1) / 4;
// Otherwise:
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() {
std::uint8_t u8 = 1;
std::uint16_t u16 = 1;
std::uint32_t u32 = 1;
std::cout << hex(unsigned(u8), 2) << ", " << hex(u16) << ", " << hex(u32) << '\n';
}
#包括
#包括
#包括
模板
结构十六进制
{
//C++11:
//静态constexpr int Width=(标准::数字限制::数字+1)/4;
//否则:
枚举{Width=(std::numeric_limits::digits+1)/4};
常数T&value;
常数整数宽度;
十六进制(常数T和值,整数宽度=宽度)
:值(值)、宽度(宽度)
{}
空写(std::ostream&stream)常量{
如果(std::numeric\u limits::radix!=2)流写一个函数以十六进制格式输出并调用它。我想更短是相对的。如果你认为printf()
后面的代码很短,我可以向你保证它绝对不是。你只需要滚动你自己的(这看起来与你这里的代码非常相似)。您可以编写一个操纵器类/运算符对,允许像std::cout这样的东西将其缩短,我会使用宏来隐藏丑陋之处,例如#define PAD_HEX(digits)std::HEX这将更好地作为注释。+1完全是我的方式,但宽度操纵器已重置(如我所记得的)在每次发布到streamoperator@WhozCraig时,我都编辑了我的答案,但我不确定它是否更好。我的意思是,为了格式化的目的,必须记住使用WrapperType
,这是你只使用函数的解决方案更好的地方。但是如果OP是懒惰的,也许这可以节省键入。