web-dev-qa-db-ja.com

バイナリ形式で印刷するためのprintfコンバータはありますか?

Printfを16進数または8進数として印刷できます。バイナリとして印刷するフォーマットタグ、または任意のベースはありますか?

私はgccを実行しています。

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

ハッキーだけど私のために働く:

#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の複数回の呼び出しを避けています。

229
William Whyte

任意のデータ型のバイナリを印刷

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

ここにあなたが望むことをするためのテクニックを実演するための簡単なハックがあります。

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

通常glibcにはバイナリ変換指定子はありません。

Glibcのprintf()ファミリーの関数にカスタム変換型を追加することは可能です。詳細は register_printf_function を参照してください。アプリケーションコードを単純化して利用できるようにする場合は、独自の%b変換を自分用に追加することもできます。

これはglibcでカスタムprintfフォーマットを実装する方法の です。

78
DGentry

あなたはスピードを向上させるために小さなテーブルを使うことができます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 私は、オプティマイザがそれほど積極的ではなく、速度の違いが明らかになっている組み込みアプリケーションを主に参照しています。

33
Shahbaz

@William Whyteの答えに基づいて、これはint81632および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
18
ideasman42

最下位ビットを印刷し、それを右側にシフトアウトします。整数がゼロになるまでこれを実行すると、先行ゼロなしで逆の順序でバイナリ表現が出力されます。再帰を使用すると、順序は非常に簡単に修正できます。

#include <stdio.h>

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

私にとって、これはこの問題に対する最も明確な解決策の1つです。 0bプレフィックスと末尾の改行文字が好きなら、私は関数をラップすることをお勧めします。

オンラインデモ

17
danijar

これは、リエントラントの問題や引数のサイズ/型の制限を受けないバージョンの関数です。

#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は任意の整数式です。

16
R..
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;
}
11
works better

"%b"をサポートしているランタイムもありますが、これは標準ではありません。

また興味深い議論のためにここに見なさい:

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

HTH

8
rlerallut

以前に投稿された答えのどれも私が探していたものとまったく同じではないので、私は答えを書きました。 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);
    }
8

このコードはあなたの必要性を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
7
mrwes

C標準ライブラリには、そのようなバイナリを出力するためのフォーマット関数はありません。 printfファミリがサポートするすべてのフォーマット操作は、人間が読めるテキストを対象としています。

6
Florian Bösch

少しOTかもしれませんが、実行しているバイナリ演算を理解したりトレースしたりするためにデバッグにのみ必要な場合は、wcalc(単純なコンソール計算機)を見てください。 -bオプションを使用すると、バイナリ出力が得られます。

例えば.

 $ wcalc -b "(256 | 3)&0xff" 
 = 0b11 
6
quinmars

バイナリ形式で印刷するための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, 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
chux

次の再帰関数が役に立つかもしれません:

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

}

私は、サイズと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;
}
4
paniq

@ ideasman42の答えに対する提案に基づいて、これはint81632および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
3
Et7f3XIV

少ないコードとリソースを使用してあらゆるタイプのビットを印刷する

このアプローチには属性があります。

  • 変数とリテラルを処理します。
  • 必要でないときにすべてのビットを反復しません。
  • 1バイトが完了したときにだけ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 )を使って全てのバイトを(ビット列として)埋めて、入力/インデックスバイトに基づいてそれらを出力しました。一見の価値があります。

3
Geyslan G. Bem

私の解決策:

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");
3
SarahGaidi

標準的でポータブルな方法はありません。

いくつかの実装は itoa() を提供しますが、ほとんどの場合はそうではありません、そしてそれはやや妙なインターフェースを持っています。しかし、コードはリンクの背後にあり、独自のフォーマッタを非常に簡単に実装できるはずです。

3
wnoise

私は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;
}
3
eMPee584

1つのステートメントgeneric 任意の整数型 を、 standard libraryを使用してバイナリ文字列表現に変換します。

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

2
luart

これは私が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 );
}
2
andre.barata

迅速で簡単な解決策:

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);
2
Robotbugs

ビット操作の問題を解決しながらこれを行うための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");
    }
}
2
Gaurav Sinha

次に、あなたにメモリレイアウトを見せます:

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

つかいます:

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

詳しくはprintfで2進数を表示する方法をご覧ください。

2
kapilddit
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
olli
#include <stdio.h>
#include <conio.h>

void main()
{
    clrscr();
    printf("Welcome\n\n\n");
    unsigned char x='A';
    char ch_array[8];
    for(int i=0; x!=0; i++)
    {
        ch_array[i] = x & 1;
        x = x >>1;
    }
    for(--i; i>=0; i--)
        printf("%d", ch_array[i]);

    getch();
}
2
rakesh jha

2進数で印刷するためのさらに別のアプローチ: 最初に整数を変換する

6をバイナリで印刷するには、6110に変更してから"110"を印刷します。

char buf[]の問題を回避します。
printf()フォーマット指定子、フラグ、および"%08lu""%*lX"のようなフィールドは、まだ簡単に使用できます。
2進法(基数2)だけでなく、この方法は16までの他の基数に拡張可能です。
小さい整数値に制限されています。

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

unsigned long char_to_bin10(char ch) {
  unsigned char uch = ch;
  unsigned long sum = 0;
  unsigned long power = 1;
  while (uch) {
    if (uch & 1) {
      sum += power;
      }
   power *= 10;
   uch /= 2;
  }
  return sum;
}

uint64_t uint16_to_bin16(uint16_t u) {
  uint64_t sum = 0;
  uint64_t power = 1;
  while (u) {
    if (u & 1) {
      sum += power;
      }
    power *= 16;
    u /= 2;
  }
  return sum;
}

void test(void) {
  printf("%lu\n", char_to_bin10(0xF1));
  // 11110001
  printf("%" PRIX64 "\n", uint16_to_bin16(0xF731));
  // 1111011100110001
}
2
chux

これは、テンプレートを使用して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
2
Leo

私は自分の解決策を投稿したいだけです。これはゼロと1バイトのものを取得するために使用されますが、この関数を数回呼び出すことはより大きなデータブロックに使用することができます。私はそれを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
Marko
/* 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" */
2
Ben Cordero

数値を16進数形式に変換してから、各16進数暗号を4つの「ビット」(1と0)にデコードするという方法もあります。 sprintfは私たちのためにビット操作をすることができます:

const char* binary(int n) {
  static const char binnums[16][5] = { "0000","0001","0010","0011",
    "0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111" };
  static const char* hexnums = "0123456789abcdef";
  static char inbuffer[16], outbuffer[4*16];
  const char *i;
  sprintf(inbuffer,"%x",n); // hexadecimal n -> inbuffer
  for(i=inbuffer; *i!=0; ++i) { // for each hexadecimal cipher
    int d = strchr(hexnums,*i) - hexnums; // store its decimal value to d
    char* o = outbuffer+(i-inbuffer)*4; // shift four characters in outbuffer
    sprintf(o,"%s",binnums[d]); // place binary value of d there
  }
  return strchr(outbuffer,'1'); // omit leading zeros
}

puts(binary(42)); // outputs 101010
1
Jan Turoň

関数を実行して呼び出す

display_binary(int n)
{
    long int arr[32];
    int arr_counter=0;
    while(n>=1)
    {
        arr[arr_counter++]=n%2;
        n/=2;
    }
    for(int i=arr_counter-1;i>=0;i--)
    {
        printf("%d",arr[i]);
    }
}
1
Esann

たぶん誰かがこの解決策が役に立つと思うでしょう:

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
Kresimir
void DisplayBinary(unsigned int n)
{
    int l = sizeof(n) * 8;
    for (int i = l - 1 ; i >= 0; i--) {
        printf("%x", (n & (1 << i)) >> i);
    }
}
1
Rassoul
void DisplayBinary(int n)
{
    int arr[8];
    int top =-1;
    while (n)
    {
        if (n & 1)
            arr[++top] = 1;
        else
            arr[++top] = 0;

        n >>= 1;
    }
    for (int i = top ; i > -1;i--)
    {
        printf("%d",arr[i]);
    }
    printf("\n");
}
1
Akhil

DOをサポートしているランタイムライブラリであっても整数値のためだけのようです。

あなたがバイナリで浮動小数点値を印刷したいならば、私はあなたが で見つけることができるいくつかのコードを書きました。

0
Rick Regan

これはとても簡単なものです:

int print_char_to_binary(char ch)
{
    int i;
    for (i=7; i>=0; i--)
        printf("%hd ", ((ch & (1<<i))>>i));
    printf("\n");
    return 0;
}
0
hiteshradia

バイナリ形式で印刷するためのprintfコンバータはありますか?

"バイナリ"出力を実現するための標準のprintfフォーマット指定子はありません。これが必要なときに私が考案した代替手段です。

Mineは、2から36までの任意の基数で機能します。基数より小さい桁に達するまで、再帰呼び出しの呼び出しフレームに数字を展開します。それからそれは後方に「行き来し」、バッファsを前方に満たし、そして戻ります。戻り値は使用されたサイズ、またはバッファが文字列を保持するのに十分な大きさでない場合は-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;
}

1つの大きな注意点: この関数は、長さを持つ "Pascal"スタイルの文字列で使用するために設計されました。その結果、conv_radは、書かれているように、バッファをnullで終了しません。より一般的なCの用途のためには、それはたぶんヌル終了するための簡単なラッパーを必要とするでしょう。あるいは印刷のために、割り当てをputchar()sに変更するだけです。

0
luser droog
void binario(int num) {
  for(int i=0;i<32;i++){
    (num&(1<i))? printf("1"):
        printf("0");
  }  
  printf("\n");
}
0
GutiMac

次の関数は、先行ゼロなしのポインタ演算を使用して、指定された符号なし整数の2進表現を返します。

const char* toBinaryString(unsigned long num)
{
    static char buffer[CHAR_BIT*sizeof(num)+1];
    char* pBuffer = &buffer[sizeof(buffer)-1];

    do *--pBuffer = '0' + (num & 1);
    while (num >>= 1);
    return pBuffer;
}

NUL static storage duration でオブジェクトを表しているので、明示的にbufferターミネータを設定する必要はないことに注意してください。

num仮パラメータの型を変更するだけで、これをunsigned long long(または別の符号なし整数)に簡単に適応させることができます。

CHAR_BITには<limits.h>を含める必要があります。

使用例は次のとおりです。

int main(void)
{
    printf(">>>%20s<<<\n", toBinaryString(1));
    printf(">>>%-20s<<<\n", toBinaryString(254));
    return 0;
}

以下のように、希望する出力で

>>>                   1<<<
>>>11111110            <<<
void PrintBinary( int Value, int Places, char* TargetString)
{
    int Mask;

    Mask = 1 << Places;

    while( Places--) {
        Mask >>= 1; /* Preshift, because we did one too many above */
        *TargetString++ = (Value & Mask)?'1':'0';
    }
    *TargetString = 0; /* Null terminator for C string */
}

呼び出し関数は文字列...を「所有」します。

char BinaryString[17];
...
PrintBinary( Value, 16, BinaryString);
printf( "yadda yadda %s yadda...\n", BinaryString);

お使いのCPUにもよりますが、PrintBinaryのほとんどの操作は1つまたはごくわずかな機械命令にしかなりません。

0
Adam

それほど効率的ではないかもしれませんが、それは非常に単純です。これを試して:

tmp1 = 1;
while(inint/tmp1 > 1) {
    tmp1 <<= 1;
}
do {
    printf("%d", tmp2=inint/tmp1);
    inint -= tmp1*tmp2;
} while((tmp1 >>= 1) > 0);
printf(" ");
0
Moses

以下の機能を使用してください。

void conbin(int num){  
        if(num != 0)
        {
            conbin(num >> 1);     
            if (num & 1){
            printf("1");
            }
            else{
            printf("0");
            }
        }
    }
0
kapilddit