16 진수 또는 8 진수로 printf를 사용하여 인쇄 할 수 있습니다. 이진 또는 임의의 기준으로 인쇄 할 형식 태그가 있습니까?
gcc를 실행 중입니다.
printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"
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의 여러 호출을 피하십시오.
printf와 함께있는 사람 static버퍼 수 없습니다입니다.
int시스템에서 32 비트 라고 가정하면 단일 32 비트 값을 인쇄하려면 32 * 4 바이트 값을위한 공간이 필요합니다. 총 128 바이트 스택 크기에 따라 문제가 될 수도 있고 아닐 수도 있습니다.
모든 데이터 유형에 대한 이진 인쇄
//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;
}
size_t i; for (i=size; i-- > 0; )피하기 위해 size_t대의 int잘못 일치.
ptr(외부 루프). 그런 다음 각 비트에 대해 현재 바이트 (내부 루프)에 대해 현재 비트 ( 1 << j)로 바이트를 마스크하십시오 . 오른쪽으로 이동하면 0 ( 0000 0000b) 또는 1 ( 0000 0001b)을 포함하는 바이트가 됩니다. format을 사용하여 결과 바이트 printf를 인쇄하십시오 %u. HTH.
>과 >=서명되지 않은 유형입니다. 0부호없는 엣지 케이스이며 덜 일반적으로 부호있는 수학과 달리 일반적으로 발생합니다 INT_MAX/INT_MIN.
다음은 원하는 것을 수행하는 기술을 보여주는 빠른 해킹입니다.
#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;
}
strcat은 루프의 각 패스에서 단일 문자를 문자열에 추가하는 비효율적 인 방법입니다. 대신 a를 추가 char *p = b;하고 내부 루프를로 바꿉니다 *p++ = (x & z) ? '1' : '0'. z256 (2 ^ 8) 대신 128 (2 ^ 7)부터 시작해야합니다. (쓰레드 안전을 위해) 사용할 버퍼에 포인터를 가져와 업데이트를 고려하십시오 inet_ntoa().
strcat()! strcat과제에 대한 역 참조 된 포인터를 사후 증가시키는 것보다 이해하기 쉽다는 데 동의 하지만 초보자도 표준 라이브러리를 올바르게 사용하는 방법을 알아야합니다. 할당을 위해 인덱스 배열을 사용하는 것이 좋은 데모 일 것입니다 (실제로 b함수를 호출 할 때마다 모두 0으로 재설정되지 않기 때문에 실제로 작동 합니다).
printf("%s + %s = %s", byte_to_binary(3), byte_to_binary(4), byte_to_binary(3+4)).
glibc에는 바이너리 변환 지정자가 없습니다.
glibc의 printf () 함수 계열에 사용자 정의 변환 유형을 추가 할 수 있습니다. register_printf_function 참조 을 참조하십시오. 응용 프로그램 코드를 단순화하여 사용할 수 있도록 사용자 지정 % b 변환을 직접 사용할 수 있습니다.
다음은 glibc에서 사용자 정의 printf 형식을 구현하는 방법 의 예 입니다.
warning: 'register_printf_function' is deprecated [-Wdeprecated-declarations]그래도 동일한 기능을 수행하는 새로운 기능이 있습니다 register_printf_specifier(). 새로운 사용의 예는 여기에서 찾을 수 있습니다 : codereview.stackexchange.com/q/219994/200418을
작은 테이블을 사용하여 속도를 향상시킬 수 있습니다 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접두사와 후행 줄 바꿈 문자 를 좋아한다면 함수를 래핑하는 것이 좋습니다.
putc('0'+(number&1), stdout);
@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
PRINTF_BYTE_TO_BINARY_INT#선택적으로 사용할 그룹화 된 버전의 정의를 추가합니다 .
다음은 재진입 문제 나 인수의 크기 / 유형에 대한 제한이없는 함수 버전입니다.
#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 *a = binary_fmt(x), *b = binary_fmt(y);이 예상대로 작동하지 않음을 알고 있어야합니다 . 호출자가 버퍼를 전달하도록하면 스토리지 요구 사항이 명시됩니다. 호출자가 실제로 원하는 경우 정적 버퍼를 자유롭게 사용할 수 있으며 동일한 버퍼의 재사용이 명시 적입니다. 또한 최신 PIC ABI에서 정적 버퍼는 일반적으로 스택의 버퍼보다 액세스하는 데 더 많은 코드가 필요합니다.
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;
}
'1'와 '0'대신 49과 48당신의 삼항에. 또한 b마지막 문자가 널 종료 자로 남아있을 수 있도록 9 자 길이 여야합니다.
static char b[9] = {0}2. 루프 밖으로 선언을 이동 int z,y;하십시오 . 3. 최종 0을 추가하십시오 b[y] = 0. 이런 식으로 재 초기화가 필요하지 않습니다.
8을로 교체해야합니다 CHAR_BIT.
빠르고 쉬운 솔루션 :
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);
이전에 게시 된 답변 중 어느 것도 내가 찾던 것이 아니므로 하나를 썼습니다. 와 함께 % 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;
} /* 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);
}
char* buffer = (char*) malloc(sizeof(char) * 50);
char *buffer = malloc(sizeof(*buffer) * 50);
표준이 아니지만 일부 런타임은 "% b"을 (를) 지원합니다.
흥미로운 토론을 보려면 여기를 참조하십시오.
http://bytes.com/forum/thread591027.html
HTH
이 코드는 최대 64 비트의 요구를 처리해야합니다. pBin & pBinFill이라는 2 개의 함수를 만들었습니다. 둘 다 동일한 작업을 수행하지만 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
width대신 일반적인 이름을 사용하기 위해 log4cxx에게 알려 주어야 합니다!
이진 형식으로 인쇄 할 printf 변환기가 있습니까?
이 printf()제품군은 표준 지정자를 사용하여 8, 10 및 16 기반으로 만 인쇄 할 수 있습니다. 코드의 특정 요구에 따라 숫자를 문자열로 변환하는 함수를 만드는 것이 좋습니다.
베이스에 인쇄하려면 [2-36]
지금까지 다른 모든 답변에는 이러한 제한 중 하나 이상이 있습니다.
리턴 버퍼에 정적 메모리를 사용하십시오. 이것은 함수가에 대한 인수로 사용될 수있는 횟수를 제한합니다 printf().
포인터를 비우려면 호출 코드가 필요한 메모리를 할당하십시오.
적절한 버퍼를 명시 적으로 제공하려면 호출 코드가 필요합니다.
printf()직접 전화하십시오 . 이것은을위한 새로운 기능 의무화 fprintf(), sprintf(), vsprintf(), 등
감소 된 정수 범위를 사용하십시오.
다음은 위의 제한이 없습니다 . 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, 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
다음과 같은 재귀 함수가 유용 할 수 있습니다.
void bin(int n)
{
/* Step 1 */
if (n > 1)
bin(n/2);
/* Step 2 */
printf("%d", n % 2);
}
크기와 C ++에 대한 최고의 솔루션을 최적화 하고이 솔루션에 도달했습니다.
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;
}
std::string제거 할 수도 있습니다 static. 가장 간단한 방법은 static한정자를 삭제 b하고 함수에 로컬로 만드는 것 입니다.
((x>>z) & 0x01) + '0'충분하다.
이 접근법은 다음과 같은 속성을 갖습니다.
#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
내가 사용한 또 다른 접근 방식 ( bitprint.h을 (비트 문자열로) 모든 바이트있는 테이블을 작성하고 입력 / 인덱스 바이트에 기반을 인쇄). 살펴볼 가치가 있습니다.
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');
}
}
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;
}
count도달 MAXCNT - 1,의 다음 증분은 count그것을 만들 것입니다 MAXCNT배열의 경계 밖으로 액세스의 원인이되는 대신 제로의. 당신은해야합니다 count = (count + 1) % MAXCNT.
MAXCNT + 1함수에 대한 호출을 사용하는 개발자에게는 놀라운 일이 될 것 printf입니다. 일반적으로 둘 이상의 옵션을 제공하려면 무한대로 만드십시오. 4와 같은 숫자는 문제를 일으킬 수 있습니다.
표준 라이브러리를 사용하여 모든 정수 유형 을 이진 문자열 표현으로 변환하는 하나의 명령문 일반 변환 :
#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);
그의 대답에 @ ideasman42의 제안을 바탕으로,이 제공하는 매크로이다 int8, 16, 32및 64재사용 버전 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
사용하다:
char buffer [33];
itoa(value, buffer, 2);
printf("\nbinary: %s\n", buffer);
더 자세한 내용은 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);
}
}
작동해야합니다-테스트되지 않았습니다.
/* 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" */
다음은 메모리 레이아웃을 보여줍니다.
#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;
}
다음은 템플릿을 사용하여 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