programing

바이너리 형식으로 인쇄할 printf 컨버터가 있나요?

shortcode 2022. 8. 23. 21:29
반응형

바이너리 형식으로 인쇄할 printf 컨버터가 있나요?

★★★로 인쇄할 수 .printf16년 8살바이너리 또는 임의의 베이스로 인쇄할 형식 태그가 있습니까?

gcc를 실행하고 있습니다.

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

해킹은 가능하지만 내 능력:

#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 여기에서는 메모리 할 수 있습니다.

모든 데이터 유형에 대한 이진 인쇄

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

속도를 높이려면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 저는 주로 옵티마이저가 그다지 공격적이지 않고 속도 차이가 눈에 띄는 임베디드 애플리케이션을 말합니다.

최하위 비트를 인쇄하여 우측으로 이동합니다.정수가 0이 될 때까지 이 작업을 수행하면 선행 0이 없는 바이너리 표현이 역순으로 인쇄됩니다.재귀를 사용하면 순서를 쉽게 수정할 수 있습니다.

#include <stdio.h>

void print_binary(unsigned int number)
{
    if (number >> 1) {
        print_binary(number >> 1);
    }
    putc((number & 1) ? '1' : '0', stdout);
}

저에게 이것은 그 문제에 대한 가장 깨끗한 해결책 중 하나입니다.에 들면0b프레픽스와 후속 줄 바꿈 문자를 사용합니다. 함수를 래핑하는 것이 좋습니다.

온라인 데모

2022년 2월 3일 현재 GNU C 라이브러리는 버전 2.35로 업데이트되었습니다.결과적으로.%b는 바이너리 형식으로 출력할 수 있게 되었습니다.

printf-family 함수는 ISO C2X 초안에 지정된 바이너리 정수 출력에 %b 형식과 ISO C2X 초안에 의해 권장되는 형식의 %B 변형을 지원합니다.

보통 glibc에는 바이너리 변환 지정자가 없습니다.

glibc의 printf() 함수 패밀리에 커스텀 변환 유형을 추가할 수 있습니다.자세한 내용은 register_printf_function을 참조하십시오.애플리케이션 코드를 간단하게 사용할 수 있는 경우 사용자 정의 %b 변환을 추가할 수 있습니다.

다음으로 glibc에서 커스텀 printf 포맷을 구현하는 예를 나타냅니다.

여기 여러분이 원하는 것을 하기 위한 기술을 시연하기 위한 빠른 해킹이 있습니다.

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

@ Whyte의@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

읽기 쉽도록 하기 위해 다음과 같은 구분 기호를 추가할 수 있습니다.

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

빠르고 쉬운 솔루션:

void printbits(my_integer_type x)
{
    for(int i=sizeof(x)<<3; i; i--)
        putchar('0'+((x>>(i-1))&1));
}

모든 크기 유형 및 서명된 int와 서명되지 않은 int에 대해 작동합니다.'&1'은 교대조가 부호 확장을 수행할 수 있으므로 서명된 int를 처리하기 위해 필요합니다.

이렇게 하는 방법은 여러 가지가 있습니다.여기 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()패밀리는 표준 지정자를 사용하여 베이스 8, 10, 16의 정수만 직접 인쇄할 수 있습니다.코드의 특정 요구에 따라 숫자를 문자열로 변환하는 함수를 만드는 것이 좋습니다.


임의의 베이스로 인쇄하려면 [2-36]

지금까지의 모든 답변에는 이러한 제한 중 적어도1개가 있습니다.

  1. 리턴 버퍼에는 스태틱메모리를 사용합니다.될 수 있는 됩니다.printf().

  2. 호출 코드가 필요한 메모리를 할당하여 포인터를 해방합니다.

  3. 적절한 버퍼를 명시적으로 제공하기 위해 발신 코드를 요구합니다.

  4. ★★printf()이렇게 ~에게 새로운 하게 됩니다.fprintf(),sprintf(),vsprintf() 등등.

  5. 축소 정수 범위를 사용합니다.

다음은 위의 제한이 없습니다.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

이 코드는 최대 64비트의 요구에 대응합니다.두 가지 .pBin ★★★★★★★★★★★★★★★★★」pBinFill 다 일을pBinFill는 마지막 인수로 지정된 채우기 문자로 선두 공백을 채웁니다.는 몇 가지 한 후 를하여 합니다.pBinFill★★★★★★ 。

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

출력:

00000001 =  0x000001 =  0b00000000000000000000000000000001
00000011 =  0x00000b =  0b00000000000000000000000000001011
00000121 =  0x000079 =  0b00000000000000000000000001111001
00001331 =  0x000533 =  0b00000000000000000000010100110011
00014641 =  0x003931 =  0b00000000000000000011100100110001
00161051 =  0x02751b =  0b00000000000000100111010100011011
01771561 =  0x1b0829 =  0b00000000000110110000100000101001
19487171 = 0x12959c3 =  0b00000001001010010101100111000011

다음은 인수 크기/유형에 대한 재진입 문제 또는 제한에 시달리지 않는 함수 버전입니다.

#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는 임의의 정수식입니다.

용도:

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

자세한 내용은 printf를 통해 이진수를 인쇄하는 방법을 참조하십시오.

이전에 올린 답변 중 제가 찾던 답변이 하나도 없어서 제가 하나 썼어요.매우 사용하기 쉽다%B와 함께printf!

/*
 * 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;
}

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

int main(int argc, char** argv)
{
    register_printf_specifier('B', printf_output_M, printf_arginfo_M);

    printf("%4B\n", 65);

    return EXIT_SUCCESS;
}

이 솔루션이 도움이 될 수도 있습니다.

void print_binary(int number, int num_digits) {
    int digit;
    for(digit = num_digits - 1; digit >= 0; digit--) {
        printf("%c", number & (1 << digit) ? '1' : '0');
    }
}

코드와 리소스를 적게 사용하여 모든 유형의 비트 인쇄

이 어프로치에는 다음과 같은 속성이 있습니다.

  • 변수 및 리터럴과 함께 작동합니다.
  • 필요하지 않은 경우 모든 비트를 반복하지 않습니다.
  • 1바이트가 완료된 경우에만 printf를 호출합니다(모든 비트가 반드시 필요한 것은 아닙니다).
  • 모든 타입에 대응합니다.
  • 거의 또는 큰 엔디안으로 동작합니다(GCC #defines를 사용하여 확인합니다).
  • char가 바이트(8비트)가 아닌 하드웨어에서 동작할 수 있습니다.(Tks @ supercat)
  • C 규격은 아니지만 대부분 정의되어 있는 type of()을 사용합니다.
#include <stdio.h>
#include <stdint.h>
#include <string.h>
#include <limits.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));       \
})

#define MSB_MASK 1 << (CHAR_BIT - 1)

void __printb(void *value, size_t size)
{
        unsigned char uc;
        unsigned char bits[CHAR_BIT + 1];

        bits[CHAR_BIT] = '\0';
        for_endian(size) {
                uc = ((unsigned char *) value)[i];
                memset(bits, '0', CHAR_BIT);
                for (int j = 0; uc && j < CHAR_BIT; ++j) {
                        if (uc & MSB_MASK)
                                bits[j] = '1';
                        uc <<= 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);
        printb('A');
        printf("\n");

        return 0;
}

산출량

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

다른 어프로치(비트프린트)를 사용하여 테이블에 모든 바이트(비트 문자열)를 채우고 입력/인덱스 바이트에 따라 인쇄합니다.한 번 볼 만해요.

C 표준 라이브러리에는 이와 같은 바이너리를 출력하는 포맷 기능이 없습니다.printf 패밀리가 지원하는 모든 형식 작업은 사람이 읽을 수 있는 텍스트를 대상으로 합니다.

다음은 템플릿을 사용하여 32비트 및 64비트 정수를 인쇄할 수 있는 paniq 솔루션의 작은 변형입니다.

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

약간 OT일 수도 있지만 실행 중인 바이너리 연산을 이해하거나 재추적하기 위한 디버깅에만 필요한 경우 wcalc(단순 콘솔 계산기)를 참조하십시오.-b 옵션을 사용하면 이진 출력을 얻을 수 있습니다.

예.

$ wcalc - b ( 256 | 3) & 0xff"
= 0b11
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');
    }

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

테스트되지 않은 상태로 작동해야 합니다.

여기 서명 안 한 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 );
}
void print_bits (uintmax_t n)
{
    for (size_t i = 8 * sizeof (int); i-- != 0;)
    {
        char c;
        if ((n & (1UL << i)) != 0)
            c = '1';
        else
            c = '0';

        printf ("%c", c);

    }
}

모든 것을 망라하는 솔루션은 아니지만, 빠르고 알기 쉬운 솔루션을 원하는 경우, 아직 아무도 이 솔루션을 제안하지 않은 것이 놀랍습니다.

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

사이즈와 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;
}

다음과 같은 재귀 함수가 유용할 수 있습니다.

void bin(int n)
{
    /* Step 1 */
    if (n > 1)
        bin(n/2);
    /* Step 2 */
    printf("%d", n % 2);
}

나의 솔루션은 printf에서 사용할 수 있는 int를 반환한다.또한 빅 엔디안 또는 리틀 엔디안 순서로 비트를 반환할 수도 있습니다.

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

int binary(uint8_t i,int bigEndian)
{
    int j=0,m = bigEndian ? 1 : 10000000;
    while (i)
    {
        j+=m*(i%2);
        if (bigEndian) m*=10; else m/=10;
        i >>= 1;
    }
    return j;
}

int main()
{
    char buf[]="ABCDEF";
    printf("\nbig endian = ");
    for (int i=0; i<5; i++) printf("%08d ",binary(buf[i],1));
    printf("\nwee endian = ");
    for (int i=0; i<5; i++) printf("%08d ",binary(buf[i],0));
    getchar();
    return 0;
}

출력

big endian = 01000001 01000010 01000011 01000100 01000101 01000110
wee endian = 10000010 01000010 11000010 00100010 10100010 01100010

표준 라이브러리를 사용하여 모든 적분 유형을 이진 문자열 표현으로 일반 변환하는 문장:

#include <bitset>
MyIntegralType  num = 10;
print("%s\n",
    std::bitset<sizeof(num) * 8>(num).to_string().insert(0, "0b").c_str()
); // prints "0b1010\n"

아니면 그냥: std::cout << std::bitset<sizeof(num) * 8>(num);

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

이 답변의 끝에 있는 함수와 매크로의 조합이 도움이 됩니다.

다음과 같이 사용합니다.

float float_var = 9.4;
SHOW_BITS(float_var);

★★★★★★Variable 'float_var': 01000001 00010110 01100110 01100110

이것은 매우 일반적이며 거의 모든 유형에서 작동할 수 있습니다.예:

struct {int a; float b; double c;} struct_var = {1,1.1,1.2};
SHOW_BITS(struct_var);

출력:

Variable `struct_var`: 00111111 11110011 00110011 00110011 00110011 00110011 00110011 00110011 00111111 10001100 11001100 11001101 00000000 00000000 00000000 00000001

코드는 다음과 같습니다.

#define SHOW_BITS(a) ({ \
    printf("Variable `%s`: ", #a);\
    show_bits(&a, sizeof(a));\
})

void show_uchar(unsigned char a)
{
    for(int i = 7; i >= 0; i-= 1) 
        printf("%d", ((a >> i) & 1));
}

void show_bits(void* a, size_t s)
{
    unsigned char* p = (unsigned char*) a;
    for(int i = s-1; i >= 0 ; i -= 1) {
        show_uchar(p[i]);
        printf(" ");
    }
    printf("\n");
}

언급URL : https://stackoverflow.com/questions/111928/is-there-a-printf-converter-to-print-in-binary-format

반응형