如何格式化c ++中的标志?

时间:2013-09-08 20:11:00

标签: c++

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

3 个答案:

答案 0 :(得分:7)

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

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

以上将产生输出:

00000000000000000000010000000001

答案 1 :(得分:1)

我意识到很多人都对使用std::bitset<N>打印相关值的方法感到满意。虽然有这样的工作,但我想指出 可以编写一个bin操纵器,虽然它有点涉及:你来自std::num_put<char>并安装使用相应方面的std::locale。以下是此方法的实现。查看底部的函数print()以查看“漂亮”代码 - 顶部只是使用std::nun_put<char>方面实现目标。

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

答案 2 :(得分:0)

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

Custom stream manipulator for streaming integers in any base