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

我正在运行gcc。

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

当前回答

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

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

其他回答

以下是我对这个问题的看法。

与大多数其他例子相比的优点:

使用putchar(),它比printf()更有效,甚至(尽管没有那么多)puts() 分成两部分(预计有内联代码),如果需要,可以提高效率。 基于非常快速的RISC算术运算(包括不使用除法和乘法)

大多数例子的缺点:

代码不是很简单。 Print_binary_size()在不复制的情况下修改输入变量。

注意:此代码的最佳结果依赖于在gcc中使用-O1或更高的值或等效值。

代码如下:

    inline void print_binary_sized(unsigned int number, unsigned int digits) {
        static char ZERO = '0';
        int digitsLeft = digits;
        
        do{
            putchar(ZERO + ((number >> digitsLeft) & 1));
        }while(digitsLeft--);
    }

    void print_binary(unsigned int number) {
        int digitsLeft = sizeof(number) * 8;
        
        while((~(number >> digitsLeft) & 1) && digitsLeft){
            digitsLeft--;
        }
        print_binary_sized(number, digitsLeft);
    }
#include <stdio.h>
#include <conio.h>

void main()
{
    clrscr();
    printf("Welcome\n\n\n");
    unsigned char x='A';
    char ch_array[8];
    for(int i=0; x!=0; i++)
    {
        ch_array[i] = x & 1;
        x = x >>1;
    }
    for(--i; i>=0; i--)
        printf("%d", ch_array[i]);

    getch();
}

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

printf()家族只能直接使用标准说明符打印以8、10和16为基数的整数。我建议创建一个函数,根据代码的特定需要将数字转换为字符串。

[Edit 2022]这预计将在C的下一个版本中改变,实现“%b”。

二进制常量,如0b10101010和printf()函数族C2x的%b转换说明符


以任何基色打印[2-36]

到目前为止,所有其他答案都至少有一个这样的局限。

使用静态内存作为返回缓冲区。这限制了函数可以作为printf()的参数使用的次数。 将需要调用代码的内存分配给释放指针。 要求调用代码显式地提供一个合适的缓冲区。 直接调用printf()。这迫使一个新函数用于fprintf(), sprintf(), vsprintf()等。 使用缩小的整数范围。

以下内容没有上述限制。它确实需要C99或更高版本,并使用“%s”。它使用复合字面值来提供缓冲空间。在printf()中多次调用它没有问题。

#include <assert.h>
#include <limits.h>
#define TO_BASE_N (sizeof(unsigned)*CHAR_BIT + 1)

//                               v--compound literal--v
#define TO_BASE(x, b) my_to_base((char [TO_BASE_N]){""}, (x), (b))

// Tailor the details of the conversion function as needed
// This one does not display unneeded leading zeros
// Use return value, not `buf`
char *my_to_base(char buf[TO_BASE_N], unsigned i, int base) {
  assert(base >= 2 && base <= 36);
  char *s = &buf[TO_BASE_N - 1];
  *s = '\0';
  do {
    s--;
    *s = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ"[i % base];
    i /= base;
  } while (i);

  // Could employ memmove here to move the used buffer to the beginning
  // size_t len = &buf[TO_BASE_N] - s;
  // memmove(buf, s, len);

  return s;
}

#include <stdio.h>
int main(void) {
  int ip1 = 0x01020304;
  int ip2 = 0x05060708;
  printf("%s %s\n", TO_BASE(ip1, 16), TO_BASE(ip2, 16));
  printf("%s %s\n", TO_BASE(ip1, 2), TO_BASE(ip2, 2));
  puts(TO_BASE(ip1, 8));
  puts(TO_BASE(ip1, 36));
  return 0;
}

输出

1020304 5060708
1000000100000001100000100 101000001100000011100001000
100401404
A2F44

做一个函数并调用它

display_binary(int n)
{
    long int arr[32];
    int arr_counter=0;
    while(n>=1)
    {
        arr[arr_counter++]=n%2;
        n/=2;
    }
    for(int i=arr_counter-1;i>=0;i--)
    {
        printf("%d",arr[i]);
    }
}

我只是想把我的解贴出来。它用于获取一个字节的0和1,但多次调用此函数可以用于更大的数据块。我将它用于128位或更大的结构。还可以修改它,使用size_t作为输入参数和指向想要打印的数据的指针,因此它可以与大小无关。但这对我很管用。

void print_binary(unsigned char c)
{
 unsigned char i1 = (1 << (sizeof(c)*8-1));
 for(; i1; i1 >>= 1)
      printf("%d",(c&i1)!=0);
}

void get_binary(unsigned char c, unsigned char bin[])
{
 unsigned char i1 = (1 << (sizeof(c)*8-1)), i2=0;
 for(; i1; i1>>=1, i2++)
      bin[i2] = ((c&i1)!=0);
}