有没有用于以二进制格式打印的printf转换器?

588

我可以使用printf将数字以十六进制或八进制形式打印出来。是否有格式标签可以打印成二进制或其他任意进制?

我正在运行gcc。


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

据我所知,使用printf是无法做到这一点的。当然,你可以编写一个辅助方法来实现这个目标,但这似乎不是你想要走的方向。 - Ian P
15
不作为ANSI标准C库的一部分--如果您正在编写可移植代码,最安全的方法是自己编写。 - tomlogic
在 C++ 中将整数类型转换为二进制字符串的一个语句标准和通用(适用于任何长度的整数类型)解决方案:https://dev59.com/dHVD5IYBdhLWcg3wBm5h#31660310 - luart
没有这种格式。但是您为什么需要它?实现二进制打印非常容易,而且很少有必要使用这种格式 - 正因为如此,所以没有被实现。 - i486
所以预期输出是1010,对吗? - Ciro Santilli OurBigBook.com
显示剩余2条评论
58个回答

3

以下是我如何为无符号整数做到的

void printb(unsigned int v) {
    unsigned int i, s = 1<<((sizeof(v)<<3)-1); // s = only most significant bit at 1
    for (i = s; i; i>>=1) printf("%d", v & i || 0 );
}

刚注意到这与@Marko的解决方案非常相似。 - andre.barata
有没有办法限制输出的位数? - Noobification
@Remian8985,变量s保存了将要输出的位数。"(sizeof(v)<<3)"基本上是输入变量的字节数(int类型为4),然后"<<3"相当于乘以8,以获取要打印的位数。 - andre.barata

3

我喜欢paniq的代码,静态缓冲区是个好主意。但是如果你想在单个printf()中使用多个二进制格式,它就会失败,因为它总是返回相同的指针并覆盖数组。

这里是一个C风格的drop-in,可以在分割缓冲区上旋转指针。

char *
format_binary(unsigned int x)
{
    #define MAXLEN 8 // width of output format
    #define MAXCNT 4 // count per printf statement
    static char fmtbuf[(MAXLEN+1)*MAXCNT];
    static int count = 0;
    char *b;
    count = count % MAXCNT + 1;
    b = &fmtbuf[(MAXLEN+1)*count];
    b[MAXLEN] = '\0';
    for (int z = 0; z < MAXLEN; z++) { b[MAXLEN-1-z] = ((x>>z) & 0x1) ? '1' : '0'; }
    return b;
}

1
一旦 count 达到 MAXCNT - 1,下一个 count 的增量将使它变为 MAXCNT 而不是零,这将导致访问数组越界。你应该执行 count = (count + 1) % MAXCNT - Shahbaz
1
顺便提一下,对于在单个 printf 中使用 MAXCNT + 1 调用此函数的开发人员来说,这将会是一个惊喜。通常,如果您想要提供超过1个选项的选项,请使其无限制。像4这样的数字可能会引起问题。 - Shahbaz

3

我的解决方案:

long unsigned int i;
for(i = 0u; i < sizeof(integer) * CHAR_BIT; i++) {
    if(integer & LONG_MIN)
        printf("1");
    else
        printf("0");
    integer <<= 1;
}
printf("\n");

2
/* Convert an int to it's binary representation */

char *int2bin(int num, int pad)
{
 char *str = malloc(sizeof(char) * (pad+1));
  if (str) {
   str[pad]='\0';
   while (--pad>=0) {
    str[pad] = num & 1 ? '1' : '0';
    num >>= 1;
   }
  } else {
   return "";
  }
 return str;
}

/* example usage */

printf("The number 5 in binary is %s", int2bin(5, 4));
/* "The number 5 in binary is 0101" */

4
支付错误分配的代价将会损害性能。把缓冲区破坏的责任推给调用者是不友善的。 - EvilTeach

2
void DisplayBinary(unsigned int n)
{
    int l = sizeof(n) * 8;
    for (int i = l - 1 ; i >= 0; i--) {
        printf("%x", (n & (1 << i)) >> i);
    }
}

我认为这是一次非常成功的头脑风暴会议,我希望Gnu libc的编写者能够选择他们最喜欢的解决方案并实现它。在2018年,我正在使用xlib显示二进制数,只要它是输入模式,二进制作为输出模式就不会过时。而且宽度也在不断变化。 - Alan Corey

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

2
下面将向您展示内存布局:
#include <limits>
#include <iostream>
#include <string>

using namespace std;

template<class T> string binary_text(T dec, string byte_separator = " ") {
    char* pch = (char*)&dec;
    string res;
    for (int i = 0; i < sizeof(T); i++) {
        for (int j = 1; j < 8; j++) {
            res.append(pch[i] & 1 ? "1" : "0");
            pch[i] /= 2;
        }
        res.append(byte_separator);
    }
    return res;
}

int main() {
    cout << binary_text(5) << endl;
    cout << binary_text(.1) << endl;

    return 0;
}

“Next will show to you memory layout” 是什么意思? - Peter Mortensen

2

A small utility function in C to do this while solving a bit manipulation problem. This goes over the string checking each set bit using a mask (1<

void
printStringAsBinary(char * input)
{
    char * temp = input;
    int i = 7, j =0;;
    int inputLen = strlen(input);

    /* Go over the string, check first bit..bit by bit and print 1 or 0
     **/

    for (j = 0; j < inputLen; j++) {
        printf("\n");
        while (i>=0) {
            if (*temp & (1 << i)) {
               printf("1");
            } else {
                printf("0");
            }
            i--;
        }
        temp = temp+1;
        i = 7;
        printf("\n");
    }
}


1
void DisplayBinary(int n)
{
    int arr[8];
    int top =-1;
    while (n)
    {
        if (n & 1)
            arr[++top] = 1;
        else
            arr[++top] = 0;

        n >>= 1;
    }
    for (int i = top ; i > -1;i--)
    {
        printf("%d",arr[i]);
    }
    printf("\n");
}

1
做一个函数并调用它。
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]);
    }
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接