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

我正在运行gcc。

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

当前回答

是否有一个printf转换器打印二进制格式?

没有标准的printf格式说明符来完成“二进制”输出。这是我在需要的时候设计的替代方案。

我的适用范围从2到36。它将数字扇出到递归调用的调用帧中,直到它到达一个比基数小的数字。然后它向后“遍历”,向前填充缓冲区,然后返回。返回值是使用的大小,如果缓冲区不够大,则返回-1。

int conv_rad (int num, int rad, char *s, int n) {
    char *vec = "0123456789" "ABCDEFGHIJKLM" "NOPQRSTUVWXYZ";
    int off;
    if (n == 0) return 0;
    if (num < rad) { *s = vec[num]; return 1; }
    off = conv_rad(num/rad, rad, s, n);
    if ((off == n) || (off == -1)) return -1;
    s[off] = vec[num%rad];
    return off+1;
}

一个重要的警告:这个函数是为“Pascal”风格的字符串设计的,它可以携带自己的长度。因此,如前所述,conv_rad不会以空终止缓冲区。对于更一般的C用法,它可能需要一个简单的包装器来执行空终止。或者对于打印,只需将赋值更改为putchar()。

其他回答

Use:

char buffer [33];
itoa(value, buffer, 2);
printf("\nbinary: %s\n", buffer);

有关更多参考,请参见如何通过printf打印二进制数。

没有标准和便携的方式。

有些实现提供了itoa(),但大多数实现中都没有,而且它的接口有些糟糕。但是代码在链接后面,应该可以让您非常容易地实现自己的格式化程序。

c

// Based on https://stackoverflow.com/a/112956/1438550

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

const char *int_to_binary_str(int x, int N_bits){
    static char b[512];
    char *p = b;
    b[0] = '\0';

    for(int i=(N_bits-1); i>=0; i--){
      *p++ = (x & (1<<i)) ? '1' : '0';
      if(!(i%4)) *p++ = ' ';
    }
    return b;
}

int main() {
  for(int i=31; i>=0; i--){
    printf("0x%08X %s \n", (1<<i), int_to_binary_str((1<<i), 32));
  }
  return 0;
}

期望的行为:

Run:
gcc -pthread -Wformat=0 -lm -o main main.c; ./main

Output:
0x80000000 1000 0000 0000 0000 0000 0000 0000 0000  
0x40000000 0100 0000 0000 0000 0000 0000 0000 0000  
0x20000000 0010 0000 0000 0000 0000 0000 0000 0000  
0x10000000 0001 0000 0000 0000 0000 0000 0000 0000  
0x08000000 0000 1000 0000 0000 0000 0000 0000 0000  
0x04000000 0000 0100 0000 0000 0000 0000 0000 0000  
0x02000000 0000 0010 0000 0000 0000 0000 0000 0000  
0x01000000 0000 0001 0000 0000 0000 0000 0000 0000  
0x00800000 0000 0000 1000 0000 0000 0000 0000 0000  
0x00400000 0000 0000 0100 0000 0000 0000 0000 0000  
0x00200000 0000 0000 0010 0000 0000 0000 0000 0000  
0x00100000 0000 0000 0001 0000 0000 0000 0000 0000  
0x00080000 0000 0000 0000 1000 0000 0000 0000 0000  
0x00040000 0000 0000 0000 0100 0000 0000 0000 0000  
0x00020000 0000 0000 0000 0010 0000 0000 0000 0000  
0x00010000 0000 0000 0000 0001 0000 0000 0000 0000  
0x00008000 0000 0000 0000 0000 1000 0000 0000 0000  
0x00004000 0000 0000 0000 0000 0100 0000 0000 0000  
0x00002000 0000 0000 0000 0000 0010 0000 0000 0000  
0x00001000 0000 0000 0000 0000 0001 0000 0000 0000  
0x00000800 0000 0000 0000 0000 0000 1000 0000 0000  
0x00000400 0000 0000 0000 0000 0000 0100 0000 0000  
0x00000200 0000 0000 0000 0000 0000 0010 0000 0000  
0x00000100 0000 0000 0000 0000 0000 0001 0000 0000  
0x00000080 0000 0000 0000 0000 0000 0000 1000 0000  
0x00000040 0000 0000 0000 0000 0000 0000 0100 0000  
0x00000020 0000 0000 0000 0000 0000 0000 0010 0000  
0x00000010 0000 0000 0000 0000 0000 0000 0001 0000  
0x00000008 0000 0000 0000 0000 0000 0000 0000 1000  
0x00000004 0000 0000 0000 0000 0000 0000 0000 0100  
0x00000002 0000 0000 0000 0000 0000 0000 0000 0010  
0x00000001 0000 0000 0000 0000 0000 0000 0000 0001 

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

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            <<<

还有一种想法是将数字转换为十六进制格式,然后将每个十六进制密码解码为四个“位”(1和0)。Sprintf可以为我们做位操作:

const char* binary(int n) {
  static const char binnums[16][5] = { "0000","0001","0010","0011",
    "0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111" };
  static const char* hexnums = "0123456789abcdef";
  static char inbuffer[16], outbuffer[4*16];
  const char *i;
  sprintf(inbuffer,"%x",n); // hexadecimal n -> inbuffer
  for(i=inbuffer; *i!=0; ++i) { // for each hexadecimal cipher
    int d = strchr(hexnums,*i) - hexnums; // store its decimal value to d
    char* o = outbuffer+(i-inbuffer)*4; // shift four characters in outbuffer
    sprintf(o,"%s",binnums[d]); // place binary value of d there
  }
  return strchr(outbuffer,'1'); // omit leading zeros
}

puts(binary(42)); // outputs 101010