Există un printf converter pentru a imprima în format binar?

Pot imprima cu printf un hex sau număr octal. Există un format de etichetă pentru a imprima ca un binar, sau arbitrare de bază?

Sunt de funcționare gcc.

printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"
Comentarii la întrebare (6)

Hacky, dar funcționează pentru mine:

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

Pentru multi-octet tipuri

printf("m: "BYTE_TO_BINARY_PATTERN" "BYTE_TO_BINARY_PATTERN"\n",
  BYTE_TO_BINARY(m>>8), BYTE_TO_BINARY(m));

Ai nevoie de tot suplimentare citate din păcate. Această abordare are o eficiență riscurile de macro-uri (don't trece o funcție ca argument pentru BYTE_TO_BINARY), dar evită probleme de memorie și mai multe invocații de strcat în unele dintre celelalte propuneri aici.

Comentarii (8)

Print Binar pentru Orice tip de Date

//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("");
}

test

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;
}
Comentarii (9)

Aici este un hack rapid pentru a demonstra tehnici de a face ceea ce vrei.

#include       /* printf */
#include      /* strcat */
#include      /* 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;
}
Comentarii (13)

Nu e't un binar specificator de conversie în glibc în mod normal.

Este posibil să adăugați personalizat tipuri de conversie la printf() familia de funcții în glibc. A se vedea registrul de_printf_function pentru detalii. Ai putea adăuga un custom %b conversie pentru uz propriu, dacă se simplifică aplicarea codului să îl ai la dispoziție.

Aici este o de exemplu de cum să pună în aplicare un obicei printf formate în glibc.

Comentarii (2)

Ai putea folosi o masă mică pentru a îmbunătăți viteza de1. Tehnici similare sunt utile în lumea încorporat, de exemplu, pentru a inversa un octet:

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 I'm cea mai mare parte referindu-se la aplicații embedded unde optimizatori nu sunt atât de agresive și diferența de viteză este vizibil.

Comentarii (0)

Imprimare bitul cel mai puțin semnificativ și trecerea pe dreapta. Face acest lucru până când întreg devine zero imprimă reprezentarea binară fără zerouri la început, dar în ordine inversă. Folosind recursivitate, ordinea poate fi corectată destul de ușor.

#include 

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

Pentru mine, aceasta este una dintre cele mai curate soluții la această problemă. Dacă vă place 0b prefix și un sfârșit de linie nouă de caractere, vă sugerez ambalaj funcția.

Demo on-line

Comentarii (3)

Bazat pe @William Whyte's a răspunde, acesta este un macro care oferă int8,16,32 & 64 versiuni, reutilizarea INT8 macro pentru a evita repetarea.

/* --- 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 
int main() {
    long long int flag = 1648646756487983144ll;
    printf("My Flag "
           PRINTF_BINARY_PATTERN_INT64 "\n",
           PRINTF_BYTE_TO_BINARY_INT64(flag));
    return 0;
}

Acest ieșiri:

My Flag 0001011011100001001010110111110101111000100100001111000000101000

Pentru lizibilitate, poate doriți să adăugați un separator de exemplu:

My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000
Comentarii (4)

Aici's o versiune de funcția care nu suferă de reentrancy probleme sau limite privind dimensiunea/tipul de argument:

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

Rețineți că acest cod ar lucra la fel de bine pentru orice bază între 2 și 10 dacă înlocuiți doar 2's de baza dorită. Utilizare este:

char tmp[FMT_BUF_SIZE];
printf("%s\n", binary_fmt(x, tmp));

Unde " x " este orice expresie integrantă.

Comentarii (16)
const char* byte_to_binary( int x )
{
    static char b[sizeof(int)*8+1] = {0};
    int y;
    long long z;
    for (z=1LL>=1,y++)
    {
        b[y] = ( ((x & z) == z) ? '1' : '0');
    }

    b[y] = 0;

    return b;
}
Comentarii (5)

Nici unul dintre postat anterior răspunsurile sunt exact ceea ce căutam, așa că am scris-o. Este super simplu de utilizat %B cu "printf"!

    /*
     * File:   main.c
     * Author: Techplex.Engineer
     *
     * Created on February 14, 2012, 9:16 PM
     */

    #include 
    #include 
    #include 
    #include 
    #include 

    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) {
            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);
    }
Comentarii (6)

Unele runtime suport "%b" deși nu este un standard.

De asemenea, a se vedea aici pentru o discuție interesantă:

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

HTH

Comentarii (1)

există un printf converter pentru a imprima în format binar?

Anii printf() familia este doar capabil de a imprima în baza 8, 10 și 16 folosind standard de proiectanti direct. Am sugerăm să creați o funcție care convertește un număr într-un șir pe cod's nevoile specifice.


Pentru a imprima în orice bază [2-36]

Toate celelalte răspunsuri de până acum au cel puțin una din aceste limite.

  1. Utilizare memorie statică pentru a reveni tampon. Acest lucru limitează numărul de ori funcția poate fi folosit ca un argument pentru printf().

  2. Aloca memorie care necesită codul de asteptare pentru indicii gratuit.

  3. Necesita asteptare cod să prevadă în mod explicit o soluție tampon corespunzătoare.

  4. Suna printf()direct. Acest lucru impune o nouă funcție pentru afprintf(),sprintf(),vsprintf()`, etc.

  5. Utilizarea redusă întreg intervalul.

Următoarele a nici unul dintre cele de mai sus limitare. Ea are nevoie de C99 sau mai târziu, și de a folosi de "%s". Se folosește o compound literal pentru a oferi spațiu tampon. Nu are probleme cu mai multe apeluri într-o printf().


#include 
#include 
#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 
Comentarii (2)

Acest cod ar trebui să se ocupe de nevoile tale de până la 64 de biți. Am creat 2 funcții pBin & pBinFill. Ambele fac acelasi lucru, dar pBinFill umple în cele mai importante spații cu fillChar. Funcția de testare generează niște date de test, apoi imprimă folosind funcția.

char pBinFill(long int x,char deci, char fillChar); // varianta cu umplere char pBin(long int x, char așa); // versiunea fără a umple #defini kDisplayWidth 64

char pBin(long int x,char deci) { char s[kDisplayWidth+1]; int i=kDisplayWidth; s[i--]=0x00; // termina string face { // se umple în matrice de la dreapta la stânga s[i--]=(x & 1) ? '1':'0'; // determina pic x>>=1; // deplasare la dreapta cu 1 bit } while( x &gt 0); i++; // la ultimul punct valabil caracter sprintf(deci,"%s",s+i); // stick-l în temp string string reveni deci; }

char* pBinFill(long int x,char *deci, char fillChar)
{ // se umple în matrice de la dreapta la stânga
 char s[kDisplayWidth+1];
 int i=kDisplayWidth;
 s[i--]=0x00; // termina string
face
 { // se umple în matrice de la dreapta la stânga
 s[i--]=(x & 1) ? '1':'0';
 x>>=1; // deplasare la dreapta cu 1 bit
 } while( x > 0);
 în timp ce(i>=0) s[i--]=fillChar; // se umple cu fillChar 
sprintf(deci,"%s",s);
 reveni deci;
}
void test()
{
 char asa[kDisplayWidth+1]; // tampon de lucru pentru pBin
 long int val=1;
face
{
 printf("%ld =\t\t%#lx =\t\t0b%s\n",val,val,pBinFill(val,deci,'0'));
 val*=11; // generarea de date de testare
 } while (val < 100000000);
}

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

Comentarii (3)

Poate un pic OT, dar dacă aveți nevoie de acest lucru numai pentru debuging să înțeleagă sau reconstitui unele operații binare faci, ai putea să te uiți pe wcalc (o simpla consola de calculator). Cu -b opțiuni veți obține binar de ieșire.

de exemplu

$ wcalc -b "(256 | 3) & 0xff"
 = 0b11
Comentarii (1)

Nu există nici o formatare funcție din biblioteca standard C pentru ieșire binare de genul asta. Toate format operațiuni printf familia sprijină sunt spre lizibil textul.

Comentarii (0)

Următoarea funcție recursivă ar putea fi utile:

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

}
Comentarii (1)

Am optimizat soluție de top pentru dimensiunea și C++-ness, si am ajuns la această soluție:

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;
}
Comentarii (2)

Nici un standard și portabil.

Unele implementări oferi itoa(), dar's nu va fi în mai, și are o oarecum dezgustător interfață. Dar codul este în spatele link-ul și ar trebui să te pună în aplicare propria formatare destul de ușor.

Comentarii (0)

Mi-a placut codul de numele de paniq, static tampon este o idee bună. Cu toate acestea eșuează dacă doriți mai multe formate binare într-un singur printf (), deoarece se întoarce mereu același pointer și suprascrie matrice.

Aici's o C stilul drop-in care se roteste pointer pe un split-tampon.

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;
}
Comentarii (2)