16 진수 또는 8 진수로 printf를 사용하여 인쇄 할 수 있습니다. 이진 또는 임의의 기준으로 인쇄 할 형식 태그가 있습니까?
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
있지만 ( 함수를의 인수로 전달하지 마십시오 ) 여기 다른 제안에서 메모리 문제와 strcat의 여러 호출을 피하십시오.
답변
모든 데이터 유형에 대한 이진 인쇄
//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;
}
답변
다음은 원하는 것을 수행하는 기술을 보여주는 빠른 해킹입니다.
#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;
}
답변
glibc에는 바이너리 변환 지정자가 없습니다.
glibc의 printf () 함수 계열에 사용자 정의 변환 유형을 추가 할 수 있습니다. register_printf_function 참조 을 참조하십시오. 응용 프로그램 코드를 단순화하여 사용할 수 있도록 사용자 지정 % b 변환을 직접 사용할 수 있습니다.
다음은 glibc에서 사용자 정의 printf 형식을 구현하는 방법 의 예 입니다.
답변
작은 테이블을 사용하여 속도를 향상시킬 수 있습니다 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(int number)
{
if (number) {
print_binary(number >> 1);
putc((number & 1) ? '1' : '0', stdout);
}
}
나에게 이것은 문제에 대한 가장 깨끗한 해결책 중 하나입니다. 0b
접두사와 후행 줄 바꿈 문자 를 좋아한다면 함수를 래핑하는 것이 좋습니다.
답변
@William 와이트의 답변에 따라,이 제공하는 매크로이다 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