我知道在 c++ 中我们可以使用 ios::showbase 之类的状态标志来格式化输出/输入...我知道我们可以将基域的标志设置为 hex、oct、dec 但是有 bin 吗?以及如何在二进制基域中格式化整数?
3 回答
您可以使用bitset<>
. 例如:
int x = 1025;
std::cout << std::bitset<32>(x) << std::endl;
以上将产生输出:
00000000000000000000010000000001
I realize that many people are happy with the approach using a std::bitset<N>
to print the relevant value. Although this sort of work, I like to point out that it is possible to write a bin
manipulator although it is a bit involved: you'd derive from std::num_put<char>
and install a std::locale
using the corresponding facet. Below is an implementation of this approach. Look at the function print()
at the bottom to see the "nice" code - the top is just making things happen with the std::nun_put<char>
facet.
#include <iostream>
#include <iomanip>
#include <locale>
#include <limits>
#include <iterator>
#include <algorithm>
int bin_index(std::ios_base::xalloc());
struct num_put
: std::num_put<char>
{
public:
num_put(std::locale const& chain)
: d_chain(std::use_facet<std::num_put<char> >(chain)) {
}
private:
#if __cplusplus == 201103L
typedef long long long_forward;
typedef unsigned long long actual_type;
#else
typedef unsigned long long_forward;
typedef unsigned long actual_type;
#endif
std::num_put<char> const& d_chain;
typedef std::num_put<char>::iter_type iter_type;
iter_type do_put(iter_type to, std::ios_base& fmt, char_type fill,
long v) const {
return fmt.iword(bin_index)
? this->put(to, fmt, fill, static_cast<long_forward>(v))
: this->d_chain.put(to, fmt, fill, v);
}
#if __cplusplus == 201103L
iter_type do_put(iter_type to, std::ios_base& fmt, char_type fill,
long long v) const {
return fmt.iword(bin_index)
? this->put(to, fmt, fill, static_cast<unsigned long long>(v))
: this->d_chain.put(to, fmt, fill, v);
}
iter_type do_put(iter_type to, std::ios_base& fmt, char_type fill,
unsigned long v) const {
return fmt.iword(bin_index)
? this->put(to, fmt, fill, static_cast<unsigned long long>(v))
: this->d_chain.put(to, fmt, fill, v);
}
#endif
iter_type do_put(iter_type to, std::ios_base& fmt, char_type fill,
actual_type v) const {
if (fmt.iword(bin_index)) {
char bits[std::numeric_limits<actual_type>::digits];
char* end(bits);
if (v == 0) {
*end++ = '0';
}
else {
for (; v; ++end) {
*end = "01"[v & 0x1u];
v >>= 1;
}
}
std::streamsize show(2 * (bool(fmt.flags()
& std::ios_base::showbase)));
std::streamsize nofill(show + end - bits < fmt.width()
? fmt.width() - (show + end - bits)
: 0);
fmt.width(0);
if (0 < nofill && (fmt.flags() & std::ios_base::right)) {
end = std::fill_n(end, nofill, fill);
}
if (fmt.flags() & std::ios_base::showbase) {
*end++ = 'b';
*end++ = '0';
}
if (0 < nofill && (fmt.flags() & std::ios_base::internal)) {
end = std::fill_n(end, nofill, fill);
}
to = std::copy(std::reverse_iterator<char*>(end),
std::reverse_iterator<char*>(bits),
to);
if (0 < nofill && (fmt.flags() & std::ios_base::left)) {
to = std::fill_n(to, nofill, fill);
}
return to;
}
else {
return this->d_chain.put(to, fmt, fill, v);
}
}
};
std::ostream& bin(std::ostream& out)
{
if (!dynamic_cast<num_put const*>(
&std::use_facet<std::num_put<char> >(out.getloc()))) {
std::locale loc(std::locale(), new num_put(out.getloc()));
out.imbue(loc);
}
out.iword(bin_index) = true;
return out;
}
std::ostream& nobin(std::ostream& out)
{
out.iword(bin_index) = false;
return out;
}
void print(int value)
{
std::cout << std::right;
std::cout << nobin << std::setw(8) << value << "="
<< bin << std::right << std::setw(20) << value << "'\n";
std::cout << nobin << std::setw(8) << value << "="
<< bin << std::internal << std::setw(20) << value << "'\n";
std::cout << nobin << std::setw(8) << value << "="
<< bin << std::left << std::setw(20) << value << "'\n";
}
int main()
{
std::cout << std::showbase;
print(0);
print(17);
print(123456);
}
您还可以添加自己的流操纵器,如下所述: