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

我正在运行gcc。

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

当前回答

这段代码可以处理64位的需求。 我创建了两个函数:pBin和pBinFill。两者都做同样的事情,但是pBinFill用最后一个参数提供的填充字符填充前导空格。 测试函数生成一些测试数据,然后使用pBinFill函数将其打印出来。

#define kDisplayWidth 64

char* pBin(long int x,char *so)
{
  char s[kDisplayWidth+1];
  int i = kDisplayWidth;
  s[i--] = 0x00;  // terminate string
  do {  // fill in array from right to left
    s[i--] = (x & 1) ? '1' : '0';  // determine bit
    x >>= 1;  // shift right 1 bit
  } while (x > 0);
  i++;  // point to last valid character
  sprintf(so, "%s", s+i);  // stick it in the temp string string
  return so;
}

char* pBinFill(long int x, char *so, char fillChar)
{
  // fill in array from right to left
  char s[kDisplayWidth+1];
  int i = kDisplayWidth;
  s[i--] = 0x00;  // terminate string
  do {  // fill in array from right to left
    s[i--] = (x & 1) ? '1' : '0';
    x >>= 1;  // shift right 1 bit
  } while (x > 0);
  while (i >= 0) s[i--] = fillChar;  // fill with fillChar 
  sprintf(so, "%s", s);
  return so;
}

void test()
{
  char so[kDisplayWidth+1];  // working buffer for pBin
  long int val = 1;
  do {
    printf("%ld =\t\t%#lx =\t\t0b%s\n", val, val, pBinFill(val, so, '0'));
    val *= 11;  // generate test data
  } while (val < 100000000);
}

输出:

00000001 =  0x000001 =  0b00000000000000000000000000000001
00000011 =  0x00000b =  0b00000000000000000000000000001011
00000121 =  0x000079 =  0b00000000000000000000000001111001
00001331 =  0x000533 =  0b00000000000000000000010100110011
00014641 =  0x003931 =  0b00000000000000000011100100110001
00161051 =  0x02751b =  0b00000000000000100111010100011011
01771561 =  0x1b0829 =  0b00000000000110110000100000101001
19487171 = 0x12959c3 =  0b00000001001010010101100111000011

其他回答

glibc中通常没有二进制转换说明符。

在glibc中,可以向printf()函数家族添加自定义转换类型。有关详细信息,请参阅register_printf_function。如果可以简化应用程序代码,您可以添加自定义%b转换供自己使用。

下面是如何在glibc中实现自定义printf格式的示例。

C标准库中没有这样输出二进制的格式化函数。printf家族支持的所有格式操作都是针对人类可读的文本。

打印最低有效位并向右移出。这样做直到整数变为零,打印的二进制表示没有前导零,但顺序相反。使用递归,可以很容易地纠正顺序。

#include <stdio.h>

void print_binary(unsigned int number)
{
    if (number >> 1) {
        print_binary(number >> 1);
    }
    putc((number & 1) ? '1' : '0', stdout);
}

对我来说,这是最干净的解决方案之一。如果您喜欢0b前缀和一个尾随的新行字符,我建议对函数进行包装。

在线演示

简单,经过测试,适用于任何无符号整数类型。没有头痛。

#include <stdint.h>
#include <stdio.h>

// Prints the binary representation of any unsigned integer
// When running, pass 1 to first_call
void printf_binary(unsigned int number, int first_call)
{
        if (first_call)
        {
                printf("The binary representation of %d is [", number);
        }
        if (number >> 1)
        {
                printf_binary(number >> 1, 0);
                putc((number & 1) ? '1' : '0', stdout);
        }
        else 
        {
                putc((number & 1) ? '1' : '0', stdout);
        }
        if (first_call)
        {
                printf("]\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);