我可以用printf打印十六进制或八进制数字。是否有格式标签打印为二进制或任意基数?

我正在运行gcc。

printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
printf("%b\n", 10); // prints "%b\n"

当前回答

使用标准库将任何整型转换为二进制字符串表示的语句泛型:

#include <bitset>
MyIntegralType  num = 10;
print("%s\n",
    std::bitset<sizeof(num) * 8>(num).to_string().insert(0, "0b").c_str()
); // prints "0b1010\n"

或者只是: std::cout << std::bitset<sizeof(num) * 8>(num);

其他回答

之前发布的答案都不是我想要的,所以我写了一个。在printf中使用%B是超级简单的!

/*
 * File:   main.c
 * Author: Techplex.Engineer
 *
 * Created on February 14, 2012, 9:16 PM
 */

#include <stdio.h>
#include <stdlib.h>
#include <printf.h>
#include <math.h>
#include <string.h>

static int printf_arginfo_M(const struct printf_info *info, size_t n, int *argtypes)
{
    /* "%M" always takes one argument, a pointer to uint8_t[6]. */
    if (n > 0) {
        argtypes[0] = PA_POINTER;
    }
    return 1;
}

static int printf_output_M(FILE *stream, const struct printf_info *info, const void *const *args)
{
    int value = 0;
    int len;

    value = *(int **) (args[0]);

    // Beginning of my code ------------------------------------------------------------
    char buffer [50] = "";  // Is this bad?
    char buffer2 [50] = "";  // Is this bad?
    int bits = info->width;
    if (bits <= 0)
        bits = 8;  // Default to 8 bits

    int mask = pow(2, bits - 1);
    while (mask > 0) {
        sprintf(buffer, "%s", ((value & mask) > 0 ? "1" : "0"));
        strcat(buffer2, buffer);
        mask >>= 1;
    }
    strcat(buffer2, "\n");
    // End of my code --------------------------------------------------------------
    len = fprintf(stream, "%s", buffer2);
    return len;
}

int main(int argc, char** argv)
{
    register_printf_specifier('B', printf_output_M, printf_arginfo_M);

    printf("%4B\n", 65);

    return EXIT_SUCCESS;
}

打印任何数据类型的二进制

// Assumes little endian
void printBits(size_t const size, void const * const ptr)
{
    unsigned char *b = (unsigned char*) ptr;
    unsigned char byte;
    int i, j;
    
    for (i = size-1; i >= 0; i--) {
        for (j = 7; j >= 0; j--) {
            byte = (b[i] >> j) & 1;
            printf("%u", byte);
        }
    }
    puts("");
}

测试:

int main(int argv, char* argc[])
{
    int i = 23;
    uint ui = UINT_MAX;
    float f = 23.45f;
    printBits(sizeof(i), &i);
    printBits(sizeof(ui), &ui);
    printBits(sizeof(f), &f);
    return 0;
}

下面的函数返回给定无符号整数的二进制表示形式,使用不带前导零的指针算术:

const char* toBinaryString(unsigned long num)
{
    static char buffer[CHAR_BIT*sizeof(num)+1];
    char* pBuffer = &buffer[sizeof(buffer)-1];

    do *--pBuffer = '0' + (num & 1);
    while (num >>= 1);
    return pBuffer;
}

注意,不需要显式设置NUL结束符,因为buffer表示一个具有静态存储持续时间的对象,该对象已经被全0填充。

通过简单地修改num形式参数的类型,可以很容易地将其适应为无符号long long(或另一个无符号整数)。

CHAR_BIT要求包含<limits.h>。

下面是一个用法示例:

int main(void)
{
    printf(">>>%20s<<<\n", toBinaryString(1));
    printf(">>>%-20s<<<\n", toBinaryString(254));
    return 0;
}

其期望输出为:

>>>                   1<<<
>>>11111110            <<<

可能有点超时,但是如果你只是为了调试来理解或回溯你正在做的一些二进制操作而需要这个,你可以看看wcalc(一个简单的控制台计算器)。使用-b选项可以得到二进制输出。

e.g.

$ wcalc -b "(256 | 3) & 0xff"
 = 0b11

我优化了顶部的解决方案的大小和c++ -ness,并得到了这个解决方案:

inline std::string format_binary(unsigned int x)
{
    static char b[33];
    b[32] = '\0';

    for (int z = 0; z < 32; z++) {
        b[31-z] = ((x>>z) & 0x1) ? '1' : '0';
    }

    return b;
}