首页 文章

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

提问于
浏览
357

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

我正在运行gcc .

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

30 回答

  • 14

    我只是想发布我的解决方案 . 它用于获取一个字节的零和一个字节,但调用此函数几次可用于更大的数据块 . 我将它用于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);
    }
    
  • 2

    也许有点OT,但是如果你需要这个只是为了理解或回溯你正在做的一些二进制操作,你可以看看wcalc(一个简单的控制台计算器) . 使用-b选项可以获得二进制输出 .

    例如

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

    打印最低位并将其移出右侧 . 执行此操作直到整数变为零将打印二进制表示而不会引导零,但按相反的顺序排列 . 使用递归,订单可以很容易地纠正 .

    #include <stdio.h>
    
    void print_binary(int number)
    {
        if (number) {
            print_binary(number >> 1);
            putc((number & 1) ? '1' : '0', stdout);
        }
    }
    

    对我来说,这是解决问题的最简洁的解决方案之一 . 如果你喜欢 0b 前缀和一个尾随的新行字符,我建议包装该函数 .

    Online demo

  • 3

    您可以使用小表来提高速度1 . 类似的技术在嵌入式世界中很有用,例如,反转一个字节:

    const char *bit_rep[16] = {
        [ 0] = "0000", [ 1] = "0001", [ 2] = "0010", [ 3] = "0011",
        [ 4] = "0100", [ 5] = "0101", [ 6] = "0110", [ 7] = "0111",
        [ 8] = "1000", [ 9] = "1001", [10] = "1010", [11] = "1011",
        [12] = "1100", [13] = "1101", [14] = "1110", [15] = "1111",
    };
    
    void print_byte(uint8_t byte)
    {
        printf("%s%s", bit_rep[byte >> 4], bit_rep[byte & 0x0F]);
    }
    

    1我主要指的是优化器不那么激进且速度差异可见的嵌入式应用程序 .

  • 2

    C中的一个小实用函数,用于解决位操作问题 . 这将通过字符串检查每个设置位使用掩码(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");
        }
    }
    
  • 5

    使用较少的代码和资源打印任何类型的位

    这种方法具有以下属性:

    • 使用变量和文字 .

    • 在不需要时不迭代所有位 .

    • 仅在完成一个字节时调用printf(并非所有位都不必要) .

    • 适用于任何类型 .

    • 使用小而大的字节序(使用GCC #defines进行检查) .

    • 使用不是C标准但主要定义的typeof() .

    #include <stdio.h>
    #include <stdint.h>
    #include <string.h>
    
    #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
    #define for_endian(size) for (int i = 0; i < size; ++i)
    #elif __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
    #define for_endian(size) for (int i = size - 1; i >= 0; --i)
    #else
    #error "Endianness not detected"
    #endif
    
    #define printb(value)                                   \
    ({                                                      \
            typeof(value) _v = value;                       \
            __printb((typeof(_v) *) &_v, sizeof(_v));       \
    })
    
    void __printb(void *value, size_t size)
    {
            uint8_t byte;
            size_t blen = sizeof(byte) * 8;
            uint8_t bits[blen + 1];
    
            bits[blen] = '\0';
            for_endian(size) {
                    byte = ((uint8_t *) value)[i];
                    memset(bits, '0', blen);
                    for (int j = 0; byte && j < blen; ++j) {
                            if (byte & 0x80)
                                    bits[j] = '1';
                            byte <<= 1;
                    }
                    printf("%s ", bits);
            }
            printf("\n");
    }
    
    int main(void)
    {
            uint8_t c1 = 0xff, c2 = 0x44;
            uint8_t c3 = c1 + c2;
    
            printb(c1);
            printb((char) 0xff);
            printb((short) 0xff);
            printb(0xff);
            printb(c2);
            printb(0x44);
            printb(0x4411ff01);
            printb((uint16_t) c3);
            printf("\n");
    
            return 0;
    }
    

    输出

    $ ./printb 
    11111111 
    11111111 
    00000000 11111111 
    00000000 00000000 00000000 11111111 
    01000100 
    00000000 00000000 00000000 01000100 
    01000100 00010001 11111111 00000001 
    00000000 01000011
    

    我使用了 another 方法(bitprint.h)来填充一个包含所有字节(作为位串)的表,并根据输入/索引字节打印它们 . 值得一看 .

  • 2

    Print Binary for Any Datatype

    //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;
    }
    
  • 5

    这是paniq解决方案的一小部分变体,它使用模板允许打印32位和64位整数:

    template<class T>
    inline std::string format_binary(T x)
    {
        char b[sizeof(T)*8+1] = {0};
    
        for (size_t z = 0; z < sizeof(T)*8; z++)
            b[sizeof(T)*8-1-z] = ((x>>z) & 0x1) ? '1' : '0';
    
        return std::string(b);
    }
    

    并且可以像:

    unsigned int value32 = 0x1e127ad;
    printf( "  0x%x: %s\n", value32, format_binary(value32).c_str() );
    
    unsigned long long value64 = 0x2e0b04ce0;
    printf( "0x%llx: %s\n", value64, format_binary(value64).c_str() );
    

    结果如下:

    0x1e127ad: 00000001111000010010011110101101
    0x2e0b04ce0: 0000000000000000000000000000001011100000101100000100110011100000
    
  • 2

    这是一个快速的黑客,以演示做你想要的技术 .

    #include <stdio.h>      /* printf */
    #include <string.h>     /* strcat */
    #include <stdlib.h>     /* strtol */
    
    const char *byte_to_binary(int x)
    {
        static char b[9];
        b[0] = '\0';
    
        int z;
        for (z = 128; z > 0; z >>= 1)
        {
            strcat(b, ((x & z) == z) ? "1" : "0");
        }
    
        return b;
    }
    
    int main(void)
    {
        {
            /* binary string to int */
    
            char *tmp;
            char *b = "0101";
    
            printf("%d\n", strtol(b, &tmp, 2));
        }
    
        {
            /* byte to binary string */
    
            printf("%s\n", byte_to_binary(5));
        }
    
        return 0;
    }
    
  • 3

    以下递归函数可能很有用:

    void bin(int n)
    {
        /* Step 1 */
        if (n > 1)
            bin(n/2);
        /* Step 2 */
        printf("%d", n % 2);
    }
    
  • 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" */
    
  • 3

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

  • 7

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

    可以将自定义转换类型添加到glibc中的printf()函数系列中 . 有关详细信息,请参阅register_printf_function . 如果它简化了应用程序代码以使其可用,则可以为自己的用途添加自定义%b转换 .

    这是如何在glibc中实现自定义printf格式的example .

  • 16

    我的解决方案

    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");
    
  • 15

    这是一个不受重入问题影响的函数版本或对参数大小/类型的限制:

    #define FMT_BUF_SIZE (CHAR_BIT*sizeof(uintmax_t)+1)
    char *binary_fmt(uintmax_t x, char buf[static FMT_BUF_SIZE])
    {
        char *s = buf + FMT_BUF_SIZE;
        *--s = 0;
        if (!x) *--s = '0';
        for(; x; x/=2) *--s = '0' + x%2;
        return s;
    }
    

    请注意,如果只是用所需的基数替换2,那么此代码对于2到10之间的任何基数都可以正常工作 . 用法是:

    char tmp[FMT_BUF_SIZE];
    printf("%s\n", binary_fmt(x, tmp));
    

    x 是任何整数表达式 .

  • 76

    这是我为unsigned int做的

    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 );
    }
    
  • 3
    const char* byte_to_binary( int x )
    {
        static char b[sizeof(int)*8+1] = {0};
        int y;
        long long z;
        for (z=1LL<<sizeof(int)*8-1,y=0; z>0; z>>=1,y++)
        {
            b[y] = ( ((x & z) == z) ? '1' : '0');
        }
    
        b[y] = 0;
    
        return b;
    }
    
  • 2
    void
    print_binary(unsigned int n)
    {
        unsigned int mask = 0;
        /* this grotesque hack creates a bit pattern 1000... */
        /* regardless of the size of an unsigned int */
        mask = ~mask ^ (~mask >> 1);
    
        for(; mask != 0; mask >>= 1) {
            putchar((n & mask) ? '1' : '0');
        }
    
    }
    
  • 25

    根据@William Whyte的回答,这是一个提供 int8163264 版本的宏,重用 INT8 宏来避免重复 .

    /* --- PRINTF_BYTE_TO_BINARY macro's --- */
    #define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
    #define PRINTF_BYTE_TO_BINARY_INT8(i)    \
        (((i) & 0x80ll) ? '1' : '0'), \
        (((i) & 0x40ll) ? '1' : '0'), \
        (((i) & 0x20ll) ? '1' : '0'), \
        (((i) & 0x10ll) ? '1' : '0'), \
        (((i) & 0x08ll) ? '1' : '0'), \
        (((i) & 0x04ll) ? '1' : '0'), \
        (((i) & 0x02ll) ? '1' : '0'), \
        (((i) & 0x01ll) ? '1' : '0')
    
    #define PRINTF_BINARY_PATTERN_INT16 \
        PRINTF_BINARY_PATTERN_INT8              PRINTF_BINARY_PATTERN_INT8
    #define PRINTF_BYTE_TO_BINARY_INT16(i) \
        PRINTF_BYTE_TO_BINARY_INT8((i) >> 8),   PRINTF_BYTE_TO_BINARY_INT8(i)
    #define PRINTF_BINARY_PATTERN_INT32 \
        PRINTF_BINARY_PATTERN_INT16             PRINTF_BINARY_PATTERN_INT16
    #define PRINTF_BYTE_TO_BINARY_INT32(i) \
        PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
    #define PRINTF_BINARY_PATTERN_INT64    \
        PRINTF_BINARY_PATTERN_INT32             PRINTF_BINARY_PATTERN_INT32
    #define PRINTF_BYTE_TO_BINARY_INT64(i) \
        PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
    /* --- end macros --- */
    
    #include <stdio.h>
    int main() {
        long long int flag = 1648646756487983144ll;
        printf("My Flag "
               PRINTF_BINARY_PATTERN_INT64 "\n",
               PRINTF_BYTE_TO_BINARY_INT64(flag));
        return 0;
    }
    

    这输出:

    My Flag 0001011011100001001010110111110101111000100100001111000000101000
    

    为了便于阅读,您可能需要添加一个分隔符,例如:

    My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
    
  • 8

    是否有以二进制格式打印的printf转换器?

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


    To print in any base [2-36]

    到目前为止,所有其他答案至少具有这些限制之一 .

    • 使用静态内存作为返回缓冲区 . 这限制了函数可以用作 printf() 的参数的次数 .

    • 分配内存,要求调用代码释放指针 .

    • 要求调用代码显式提供合适的缓冲区 .

    • 直接致电 printf() . 这要求 fprintf()sprintf()vsprintf() 等新功能 .

    • 使用缩小的整数范围 .

    以下是 none of the above limitation . 它确实需要C99或更高版本并使用 "%s" . 它使用compound literal来提供缓冲区空间 . 在 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, 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
    
      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
    
  • 5

    Hacky但对我有用:

    #define BYTE_TO_BINARY_PATTERN "%c%c%c%c%c%c%c%c"
    #define BYTE_TO_BINARY(byte)  \
      (byte & 0x80 ? '1' : '0'), \
      (byte & 0x40 ? '1' : '0'), \
      (byte & 0x20 ? '1' : '0'), \
      (byte & 0x10 ? '1' : '0'), \
      (byte & 0x08 ? '1' : '0'), \
      (byte & 0x04 ? '1' : '0'), \
      (byte & 0x02 ? '1' : '0'), \
      (byte & 0x01 ? '1' : '0')
    
    printf("Leading text "BYTE_TO_BINARY_PATTERN, BYTE_TO_BINARY(byte));
    

    对于多字节类型

    printf("m: "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n",
      BYTE_TO_BINARY(m>>8), BYTE_TO_BINARY(m));
    

    不幸的是,你需要所有额外的报价 . 这种方法具有宏的效率风险(不要将函数作为参数传递给 BYTE_TO_BINARY ),但是在这里的一些其他提议中避免了内存问题和strcat的多次调用 .

  • 5

    接下来将向您展示内存布局:

    #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;
    }
    
  • 212

    没有标准和便携的方式 .

    有些实现提供itoa(),但它不会出现在大多数情况下,并且它有一些有点糟糕的界面 . 但代码在链接后面,应该让你很容易实现自己的格式化程序 .

  • 3

    一些运行时支持“%b”,尽管这不是标准 .

    另见这里有趣的讨论:

    http://bytes.com/forum/thread591027.html

    HTH

  • 5

    此代码应满足您最多64位的需求 . 我创建了2个函数pBin&pBinFill . 两者都做同样的事情,但是pBinFill用fillChar填充前导空格 . 测试功能生成一些测试数据,然后使用该功能将其打印出来 .

    char* pBinFill(long int x,char *so, char fillChar); // version with fill
    char* pBin(long int x, char *so);                   // version without fill
    #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);
    }
    
    Output:
    00000001 =  0x000001 =  0b00000000000000000000000000000001
    00000011 =  0x00000b =  0b00000000000000000000000000001011
    00000121 =  0x000079 =  0b00000000000000000000000001111001
    00001331 =  0x000533 =  0b00000000000000000000010100110011
    00014641 =  0x003931 =  0b00000000000000000011100100110001
    00161051 =  0x02751b =  0b00000000000000100111010100011011
    01771561 =  0x1b0829 =  0b00000000000110110000100000101001
    19487171 = 0x12959c3 =  0b00000001001010010101100111000011
    
  • 149

    基于@ ideasman42在他的回答中提出的建议,这是一个提供 int8163264 版本的宏,重用 INT8 宏来避免重复 .

    /* --- PRINTF_BYTE_TO_BINARY macro's --- */
    #define PRINTF_BINARY_SEPARATOR
    #define PRINTF_BINARY_PATTERN_INT8 "%c%c%c%c%c%c%c%c"
    #define PRINTF_BYTE_TO_BINARY_INT8(i)    \
        (((i) & 0x80ll) ? '1' : '0'), \
        (((i) & 0x40ll) ? '1' : '0'), \
        (((i) & 0x20ll) ? '1' : '0'), \
        (((i) & 0x10ll) ? '1' : '0'), \
        (((i) & 0x08ll) ? '1' : '0'), \
        (((i) & 0x04ll) ? '1' : '0'), \
        (((i) & 0x02ll) ? '1' : '0'), \
        (((i) & 0x01ll) ? '1' : '0')
    
    #define PRINTF_BINARY_PATTERN_INT16 \
        PRINTF_BINARY_PATTERN_INT8               PRINTF_BINARY_SEPARATOR              PRINTF_BINARY_PATTERN_INT8
    #define PRINTF_BYTE_TO_BINARY_INT16(i) \
        PRINTF_BYTE_TO_BINARY_INT8((i) >> 8),   PRINTF_BYTE_TO_BINARY_INT8(i)
    #define PRINTF_BINARY_PATTERN_INT32 \
        PRINTF_BINARY_PATTERN_INT16              PRINTF_BINARY_SEPARATOR              PRINTF_BINARY_PATTERN_INT16
    #define PRINTF_BYTE_TO_BINARY_INT32(i) \
        PRINTF_BYTE_TO_BINARY_INT16((i) >> 16), PRINTF_BYTE_TO_BINARY_INT16(i)
    #define PRINTF_BINARY_PATTERN_INT64    \
        PRINTF_BINARY_PATTERN_INT32              PRINTF_BINARY_SEPARATOR              PRINTF_BINARY_PATTERN_INT32
    #define PRINTF_BYTE_TO_BINARY_INT64(i) \
        PRINTF_BYTE_TO_BINARY_INT32((i) >> 32), PRINTF_BYTE_TO_BINARY_INT32(i)
    /* --- end macros --- */
    
    #include <stdio.h>
    int main() {
        long long int flag = 1648646756487983144ll;
        printf("My Flag "
               PRINTF_BINARY_PATTERN_INT64 "\n",
               PRINTF_BYTE_TO_BINARY_INT64(flag));
        return 0;
    }
    

    这输出:

    My Flag 0001011011100001001010110111110101111000100100001111000000101000
    

    为了便于阅读,您可以更改: #define PRINTF_BINARY_SEPARATOR#define PRINTF_BINARY_SEPARATOR ","#define PRINTF_BINARY_SEPARATOR " "

    这将输出:

    My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
    

    要么

    My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000
    
  • 7
    void print_ulong_bin(const unsigned long * const var, int bits) {
            int i;
    
            #if defined(__LP64__) || defined(_LP64)
                    if( (bits > 64) || (bits <= 0) )
            #else
                    if( (bits > 32) || (bits <= 0) )
            #endif
                    return;
    
            for(i = 0; i < bits; i++) { 
                    printf("%lu", (*var >> (bits - 1 - i)) & 0x01);
            }
    }
    

    应该工作 - 未经测试 .

  • 2

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

    这是一个C风格的插件,可以在分割缓冲区上旋转指针 .

    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;
    }
    
  • 4

    以前发布的答案都不是我想要的,所以我写了一个 . 使用 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;
        } /* printf_arginfo_M */
    
        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;
        } /* printf_output_M */
    
        int main(int argc, char** argv) {
    
            register_printf_specifier('B', printf_output_M, printf_arginfo_M);
    
            printf("%4B\n", 65);
    
            return (EXIT_SUCCESS);
        }
    
  • 11

    我优化了尺寸和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;
    }
    

相关问题