Существует ли конвертер printf для печати в двоичном формате?

Я могу вывести с помощью printf шестнадцатеричное или восьмеричное число. Существует ли тег формата для печати в двоичном виде или в виде произвольной базы?

Я использую gcc.

printf("%d %x %o\n", 10, 10, 10); //prints "10 A 12\n"
print("%b\n", 10); // prints "%b\n"
Комментарии к вопросу (6)

Суховато, но работает для меня:

#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 в некоторых других предложениях здесь.

Комментарии (8)

Печать бинарных для любого типа данных

//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;
}
Комментарии (9)

Вот быстрый хак, чтобы продемонстрировать методы, чтобы делать то, что вы хотите.

#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;
}
Комментарии (13)

Нет'т двоичный спецификатор преобразования в glibc нормально.

Можно добавить пользовательские типы преобразования функции printf() семейство функций glibc. См. <а href="и http://www.gnu.org/software/libc/manual/html_node/Customizing-Printf.html"&ГТ; зарегистрироваться _function_printf\&ЛТ;/а&ГТ; для деталей. Можно добавить пользовательское %конверсии B для собственного использования, если это упрощает код приложения, чтобы иметь доступ к ней.

Вот в <а href="и http://codingrelic.geekhold.com/2008/12/printf-acular.html" и GT;пример&ЛТ;/а&ГТ; как реализовать пользовательские функции printf форматов в glibc.

Комментарии (2)

Вы можете использовать маленький столик, чтобы улучшить скорость&ЛТ;суп&ГТ;1&ЛТ;/суп&ГТ;. Подобные методы являются полезными в embedded мире, например, инвертирование байта:

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&ЛТ;/с SUP> Я'м, ссылаясь на встраиваемые приложения, где оптимизаторы не так агрессивно, и разница в скорости видна.

Комментарии (0)

Печать наименьшего значащего бита и сдвиг на право. Делаем это до тех пор, пока число не станет равным нулю печатает двоичное представление числа без ведущих нулей, но в обратном порядке. Используя рекурсию, заказ может быть исправлено довольно легко.

#include 

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

Для меня это одна из самых чистых решений проблемы. Если вам нравится префикс и завершающий символ новой строки, я предлагаю оборачивать функцию.

Демо

Комментарии (3)

На основе @Уильям Уайт'ы ответьте, это макрос, который обеспечивает 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 
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
Комментарии (4)

Здесь'ы на версию функции, которая не страдает от реентерабельность проблемы или ограничения на размер/тип аргумента:

#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 и 10, если вы просто замените 2's на нужные базы. Использование:

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

Где X - любое целостное выражение.

Комментарии (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;
}
Комментарии (5)

Ни один из ранее опубликованы ответы на них именно то, что я ищу, поэтому я написал. Это супер проста в использовании %B С Е!

    /*
     * 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);
    }
Комментарии (6)

Некоторые среды выполнения поддерживают "%b", хотя это не является стандартом.

Интересное обсуждение см. также здесь:

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

HTH

Комментарии (1)

Есть ли конвертер функции printf для печати в двоичном формате?

В функции printf() семья может только распечатать в основание 8, 10 и 16 с помощью стандартных описателей напрямую. Я предлагаю создать функцию, которая преобразует число в строку в код'с особыми нуждами.


Распечатать в любое основание [2-36]

Все остальные ответы до сих пор имеют по крайней мере одно из этих ограничений.

  1. Использование статической памяти для возвращения буфера. Это ограничивает количество раз, когда функция может быть использована в качестве аргумента для функции printf()`.

  2. Выделить память, требующему код на бесплатную указатели.

  3. Требуют вызывающий код, чтобы явно предоставить соответствующий буфер.

  4. Называть функции printf () напрямую. Это обязывает новую функцию для fprintf(), функции sprintf(), vsprintf () и т. д.

  5. Использовать уменьшенный диапазон целых чисел.

Следующий имеет ни один из перечисленных выше ограничений. Это требует С99 или поздно и использование в "%Ы" и. Он использует literal_ _compound для обеспечения буферного пространства. Он не имеет никаких проблем с нескольких вызовов в функции 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 
Комментарии (2)

Этот код должен обрабатывать ваши потребности до 64 бит. Я создал 2 функции pBin &амп; pBinFill. Оба делают то же самое, но pBinFill заполняет пробелы с fillChar. Функция тестирования генерирует тестовые данные, затем печатает его, используя функцию.

в <предварительно&ГТ;&ЛТ;код&ГТ;

типа char pBinFill(длинный тип int х,шар поэтому, голец fillChar); // вариант с заливкой типа char pBin(длинный тип int х, типа char так); // версия без заполнения на #определять kDisplayWidth 64

голец pBin(длинный тип int х,символ так) { чар ы[kDisplayWidth+1]; int я=kDisplayWidth; с[я -]=0х00; // завершить строку делать { // заполняем массив справа налево с[Я -]=(х &амп; 1) ? '1':'0'; // определить бит х&амп;ГТ;&амп;ГТ;=1; // сдвиг вправо на 1 бит } а( х &амп;ГТ 0); я++; // точка в последний допустимый символ функции sprintf(так, на"%Ы" В,С+я); // вставить его в temp строка строка возвращение так; } &ЛТ;/код&ГТ;&ЛТ;/пре&ГТ;

в <предварительно&ГТ;&ЛТ;код&ГТ; голец pBinFill(длинный тип int х,символ так, чар fillChar) { // заполняем массив справа налево чар ы[kDisplayWidth+1]; int я=kDisplayWidth; с[я -]=0х00; // завершить строку делать { // заполняем массив справа налево с[Я -]=(х &амп; 1) ? '1':'0'; х&амп;ГТ;&амп;ГТ;=1; // сдвиг вправо на 1 бит } а( х &амп;ГТ; 0); пока(я&амп;ГТ;=0) С[я -]=fillChar; // заполнить fillChar функции sprintf(так, на"%Ы" и,ы); возвращение так; } &ЛТ;/код&ГТ;&ЛТ;/пре&ГТ; в <предварительно&ГТ;&ЛТ;код&ГТ; недействительными тест() { Чара так[kDisplayWidth+1]; // буфер для работы pBin длинный вал инт=1; делать { функции printf(" по%ЛД =\т\т%#ЛК =\Т\t0b%я\с N&;, Вэл,Вэл,pBinFill(вал,так,'0')); Вэл*=11; // генерировать тестовые данные } пока (Вэл &амп;ЛТ; 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 &ЛТ;/код&ГТ;&ЛТ;/пре&ГТ;

Комментарии (3)

Может быть, немного ОТ, но если тебе это нужно только для отладки, чтобы понять или повторить некоторые бинарные операции вы делаете, вы могли бы взглянуть на wcalc (простой калькулятор консоли). С -B параметры, вы получаете двоичного выхода.

например в <предварительно&ГТ; $ wcalc -в ”(256 | 3) &амп; значение 0xFF"и = 0b11 &ЛТ;/пред&ГТ;

Комментарии (1)

В стандартной библиотеке C нет функции форматирования для вывода двоичных данных подобным образом. Все операции форматирования, поддерживаемые семейством printf, направлены на создание текста, читаемого человеком.

Комментарии (0)

Следующая рекурсивная функция может быть полезной:

void bin(int n)
{
    /* Step 1 */
    if (n > 1)
        bin(n/2);
    /* Step 2 */
    printf("%d", n % 2);
}
Комментарии (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');
    }

}
Комментарии (1)

Я оптимизировал лучшие решения для размер и 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;
}
Комментарии (2)

Нет стандартного и портативного способа.

Некоторые реализации предоставляют itoa(), но это не будет в большинстве, и у него несколько некачественный интерфейс. Но код находится за ссылкой и должен позволить вам реализовать свой собственный форматтер довольно легко.

Комментарии (0)

Мне понравился код на Игра paniq, статический буфер-это хорошая идея. Однако это не удается, если вы хотите использовать несколько двоичных форматов в одной функции printf (), потому что она всегда возвращает тот же указатель и перезаписывает массив.

Здесь'ы с падени-в стиле, который вращает указатель на буфер сплит.

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;
}
Комментарии (2)