7

如果我想在流上输出一个固定宽度的 4 位十六进制数字,我需要执行以下操作:

cout << "0x" << hex << setw(4) << setfill('0') << 0xABC;

这似乎有点啰嗦。使用宏有助于:

#define HEX(n) "0x" << hex << setw(n) << setfill('0')

cout << HEX(4) << 0xABC;

有没有更好的方法来组合机械手?

4

3 回答 3

19

尽可能避免使用宏!他们隐藏代码,使事情难以调试,不尊重范围等。

您可以使用 KenE 提供的简单功能。如果你想变得花哨和灵活,那么你可以编写自己的操纵器:

#include <iostream>
#include <iomanip>
using namespace std;

ostream& hex4(ostream& out)
{
    return out << "0x" << hex << setw(4) << setfill('0');
}

int main()
{
    cout << hex4 << 123 << endl;
}

这使它更通用一点。可以使用上面的函数的原因是因为operator<<已经像这样重载了:ostream& operator<<(ostream&, ostream& (*funtion_ptr)(ostream&)). endl和其他一些机械手也是这样实现的。

如果要允许在运行时指定位数,我们可以使用一个类:

#include <iostream>
#include <iomanip>
using namespace std;

struct formatted_hex
{
    unsigned int n;
    explicit formatted_hex(unsigned int in): n(in) {}
};

ostream& operator<<(ostream& out, const formatted_hex& fh)
{
    return out << "0x" << hex << setw(fh.n) << setfill('0');
}

int main()
{
    cout << formatted_hex(4) << 123 << endl;
}

但是,如果可以在编译时确定大小,不妨只使用函数模板 [感谢 Jon Purdy 的建议]:

template <unsigned int N>
ostream& formatted_hex(ostream& out)
{
    return out << "0x" << hex << setw(N) << setfill('0');
}

int main()
{
    cout << formatted_hex<4> << 123 << endl;
}
于 2010-07-01T15:59:54.273 回答
4

为什么是宏——你不能用一个函数来代替吗?

void write4dhex(ostream& strm, int n)
{
    strm << "0x" << hex << setw(4) << setfill('0') << n;
}
于 2010-07-01T15:51:58.263 回答
1

在 C++20 中,您将能够使用它std::format来减少冗长:

std::cout << std::format("0x{:04x}", 0xABC);  

输出:

0x0abc

您还可以通过将格式字符串存储在常量中来轻松地重用它。

同时你可以使用基于的 {fmt}std::format。{fmt} 还提供了print使这更容易和更高效的功能(godbolt):

fmt::print("0x{:04x}", 0xABC); 

免责声明:我是 {fmt} 和 C++20 的作者std::format

于 2021-03-05T00:32:05.963 回答