我可以用printf打印十六进制或八进制数字。是否有格式标签打印为二进制或任意基数?
我正在运行gcc。
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
printf("%b\n", 10); // prints "%b\n"
我可以用printf打印十六进制或八进制数字。是否有格式标签打印为二进制或任意基数?
我正在运行gcc。
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
printf("%b\n", 10); // prints "%b\n"
当前回答
根据@William Whyte的回答,这是一个提供int8、16,32和64版本的宏,重用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
为了可读性,你可能需要为eg添加分隔符:
My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
其他回答
简单,经过测试,适用于任何无符号整数类型。没有头痛。
#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");
}
}
glibc中通常没有二进制转换说明符。
在glibc中,可以向printf()函数家族添加自定义转换类型。有关详细信息,请参阅register_printf_function。如果可以简化应用程序代码,您可以添加自定义%b转换供自己使用。
下面是如何在glibc中实现自定义printf格式的示例。
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);
}
}
应该工作-未经测试。
快速简单的解决方法:
void printbits(my_integer_type x)
{
for(int i=sizeof(x)<<3; i; i--)
putchar('0'+((x>>(i-1))&1));
}
适用于任何大小类型以及有符号整型和无符号整型。'&1'需要处理有符号整型,因为移位可能会进行符号扩展。
有很多方法可以做到这一点。这里有一个超级简单的方法,用于从有符号或无符号32位类型中打印32位或n位(如果有符号,则不输入负号,只打印实际的位),并且不返回回车符。注意,i在移位前递减:
#define printbits_n(x,n) for (int i=n;i;i--,putchar('0'|(x>>i)&1))
#define printbits_32(x) printbits_n(x,32)
如果返回一个包含稍后存储或打印的比特的字符串呢?你可以分配内存并返回它,用户必须释放它,或者你返回一个静态字符串,但如果它再次被调用,或者被另一个线程调用,它会被破坏。两种方法显示:
char *int_to_bitstring_alloc(int x, int count)
{
count = count<1 ? sizeof(x)*8 : count;
char *pstr = malloc(count+1);
for(int i = 0; i<count; i++)
pstr[i] = '0' | ((x>>(count-1-i))&1);
pstr[count]=0;
return pstr;
}
#define BITSIZEOF(x) (sizeof(x)*8)
char *int_to_bitstring_static(int x, int count)
{
static char bitbuf[BITSIZEOF(x)+1];
count = (count<1 || count>BITSIZEOF(x)) ? BITSIZEOF(x) : count;
for(int i = 0; i<count; i++)
bitbuf[i] = '0' | ((x>>(count-1-i))&1);
bitbuf[count]=0;
return bitbuf;
}
电话:
// memory allocated string returned which needs to be freed
char *pstr = int_to_bitstring_alloc(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr);
free(pstr);
// no free needed but you need to copy the string to save it somewhere else
char *pstr2 = int_to_bitstring_static(0x97e50ae6, 17);
printf("bits = 0b%s\n", pstr2);
是否有一个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()。