有没有结合流操纵器的好方法?

发布于 2024-09-07 11:27:49 字数 341 浏览 1 评论 0原文

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

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

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

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

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

是否有更好的方法来组合操纵器?

If I wanted to output a fixed width hex number with 4 digits on a stream, I would need to do something like this:

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

which seems a bit long winded. Using a macro helps:

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

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

Is there a better way to combine the manipulators?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

魔法少女 2024-09-14 11:27:49

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

您可以使用 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&运算符<<(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;
}

Avoid the macros when you can! They hide code, making things hard to debug, don't respect scope, etc.

You can use a simple function as KenE provided. If you want to get all fancy and flexible, then you can write your own manipulator:

#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;
}

This makes it a little more general. The reason the function above can be used is because operator<< is already overloaded like this: ostream& operator<<(ostream&, ostream& (*funtion_ptr)(ostream&)). endl and some other manipulators are also implemented like this.

If you want to allow the number of digits to be specified at runtime, we can use a class:

#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;
}

If the size can be determined at compile-time, however, might as well just use a function template [thanks to Jon Purdy for this suggestion]:

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;
}
み零 2024-09-14 11:27:49

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

void write4dhex(ostream& strm, int n)
{
    strm << "0x" << hex << setw(4) << setfill('0') << n;
}

Why a macro - can't you use a function instead?

void write4dhex(ostream& strm, int n)
{
    strm << "0x" << hex << setw(4) << setfill('0') << n;
}
厌味 2024-09-14 11:27:49

在 C++20 中,您将能够使用 std::format< /code>让其变得更加简洁:

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

输出:

0x0abc

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

同时,您可以使用{fmt} 库std::format 是基于。 {fmt} 还提供了 print 功能,使这变得更加简单和高效 (godbolt< /a>):

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

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

In C++20 you'll be able to use std::format to make this much less verbose:

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

Output:

0x0abc

You can also easily reuse the format string by storing it in a constant.

In the meantime you can use the {fmt} library, std::format is based on. {fmt} also provides the print function that makes this even easier and more efficient (godbolt):

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

Disclaimer: I'm the author of {fmt} and C++20 std::format.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文