3

我知道在 c++ 中我们可以使用 ios::showbase 之类的状态标志来格式化输出/输入...我知道我们可以将基域的标志设置为 hex、oct、dec 但是有 bin 吗?以及如何在二进制基域中格式化整数?

4

3 回答 3

8

您可以使用bitset<>. 例如:

    int x = 1025;
    std::cout << std::bitset<32>(x) << std::endl;

以上将产生输出:

00000000000000000000010000000001
于 2013-09-08T20:18:54.140 回答
1

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);
}
于 2013-09-08T21:27:42.810 回答
0

您还可以添加自己的流操纵器,如下所述:

用于在任何基础上流式传输整数的自定义流操纵器

于 2013-09-08T20:48:09.993 回答