Existe-t-il un convertisseur printf pour imprimer en format binary?

Je peux imprimer avec printf en nombre hexadécimal ou octal. Existe-t-il une balise de format à imprimer en tant que base binary ou arbitraire?

Je cours gcc.

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

Hacky mais travaille pour moi:

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

Pour les types multi-octets

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

Vous avez malheureusement besoin de toutes les citations supplémentaires. Cette approche présente les risques d’efficacité des macros (ne transmettez pas une fonction en tant qu’argument à BYTE_TO_BINARY ), mais évitez les problèmes de mémoire et les appels multiples de strcat dans certaines des autres propositions ici.

Impression binary pour tout type de données

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

tester

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

Voici un rapide hack pour démontrer des techniques pour faire ce que vous voulez.

 #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 ssortingng to int */ char *tmp; char *b = "0101"; printf("%d\n", strtol(b, &tmp, 2)); } { /* byte to binary ssortingng */ printf("%s\n", byte_to_binary(5)); } return 0; } 

Il n’y a pas de spécificateur de conversion binary dans la glibc normalement.

Il est possible d’append des types de conversion personnalisés à la famille de fonctions printf () dans la glibc. Voir register_printf_function pour plus de détails. Vous pouvez append une conversion% b personnalisée pour votre propre usage, si cela simplifie le code de l’application pour qu’elle soit disponible.

Voici un exemple d’implémentation d’un format d’impression personnalisé dans la glibc.

Vous pouvez utiliser une petite table pour améliorer la vitesse 1 . Des techniques similaires sont utiles dans le monde embarqué, par exemple pour inverser 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 Je fais surtout référence aux applications embarquées où les optimiseurs ne sont pas trop agressifs et où la différence de vitesse est visible.

Voici une version de la fonction qui ne souffre pas de problèmes de réentrance ou de limites de taille / type d’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; } 

Notez que ce code fonctionnerait tout aussi bien pour n’importe quelle base entre 2 et 10 si vous remplacez simplement les 2 par la base souhaitée. Utilisation est:

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

x est une expression intégrale.

Basé sur la réponse de @William Whyte, il s’agit d’une macro qui fournit des int8 , 16 , 32 et 64 , réutilisant la macro INT8 pour éviter les répétitions.

 /* --- 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; } 

Cela produit:

 My Flag 0001011011100001001010110111110101111000100100001111000000101000 

Pour plus de lisibilité, vous pouvez append un séparateur pour par exemple:

 My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000 

Imprimez le bit le moins significatif et déplacez-le vers la droite. Faire ceci jusqu’à ce que l’entier devienne nul imprime la représentation binary sans zéros non significatifs, mais dans l’ordre inverse. En utilisant la récursivité, l’ordre peut être corrigé assez facilement.

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

Pour moi, c’est l’une des solutions les plus propres au problème. Si vous aimez le préfixe 0b et un nouveau caractère de ligne, je vous suggère d’envelopper la fonction.

Démo en ligne

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

Aucune des réponses précédemment affichées n’est exactement ce que je cherchais, alors j’en ai écrit une. C’est super simple d’utiliser% B avec le 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) 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); } 

Certains runtimes supportent “% b” bien que ce ne soit pas une norme.

Voir aussi ici pour une discussion intéressante:

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

HTH

Ce code devrait gérer vos besoins jusqu’à 64 bits. J’ai créé 2 fonctions pBin & pBinFill. Les deux font la même chose, mais pBinFill remplit les espaces de début avec fillChar. La fonction de test génère des données de test, puis les imprime en utilisant la fonction.

 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 ssortingng 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 ssortingng ssortingng 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 ssortingng 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 

Peut-être un peu OT, mais si vous en avez besoin uniquement pour déboguer afin de comprendre ou de retracer certaines opérations binarys que vous effectuez, vous pouvez jeter un oeil sur wcalc (une simple calculasortingce de console). Avec les options -b, vous obtenez une sortie binary.

par exemple

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

J’ai optimisé la solution supérieure en termes de taille et de C ++, et j’ai abouti à cette solution:

 inline std::ssortingng 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; } 

Il n’y a pas de fonction de formatage dans la bibliothèque standard C pour sortir un fichier binary comme celui-ci. Toutes les opérations de formatage supscopes par la famille printf sont orientées vers un texte lisible par l’homme.

La fonction récursive suivante pourrait être utile:

 void bin(int n) { /* Step 1 */ if (n > 1) bin(n/2); /* Step 2 */ printf("%d", n % 2); } 

Existe-t-il un convertisseur printf pour imprimer en format binary?

La famille printf() peut uniquement imprimer en base 8, 10 et 16 en utilisant directement les spécificateurs standard. Je suggère de créer une fonction qui convertit le nombre en chaîne par besoin particulier du code.


Imprimer dans n’importe quelle base [2-36]

Toutes les autres réponses à ce jour ont au moins une de ces limitations.

  1. Utilisez la mémoire statique pour le tampon de retour. Cela limite le nombre de fois que la fonction peut être utilisée comme argument pour printf() .

  2. Allouer de la mémoire nécessitant le code d’appel pour libérer des pointeurs.

  3. Exiger que le code d’appel fournisse explicitement un tampon approprié.

  4. Appelez directement printf() . Cela oblige à une nouvelle fonction pour vsprintf() , vsprintf() , vsprintf() , etc.

  5. Utilisez une plage d’entiers réduite.

Ce qui suit n’a aucune des limitations ci-dessus . Il nécessite C99 ou supérieur et l’utilisation de "%s" . Il utilise un littéral composé pour fournir l’espace tampon. Il n’y a pas de problème avec plusieurs appels dans un 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 <= 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  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)); return 0; } 

Sortie

 1020304 5060708 1000000100000001100000100 101000001100000011100001000 100401404 

J’ai aimé le code par paniq, le tampon statique est une bonne idée. Cependant, il échoue si vous voulez plusieurs formats binarys dans un seul printf (), car il renvoie toujours le même pointeur et écrase le tableau.

Voici une liste déroulante de style C qui fait pivoter le pointeur sur un tampon partagé.

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

Pas de moyen standard et portable.

Certaines implémentations fournissent itoa () , mais cela ne va pas être dans la plupart des cas, et son interface est un peu désordonnée. Mais le code est derrière le lien et devrait vous permettre d’implémenter facilement votre propre formateur.

Imprimer des bits de tout type en utilisant moins de code et de ressources

Cette approche a comme atsortingbuts:

  • Fonctionne avec des variables et des littéraux.
  • N’itère pas tous les bits lorsque cela n’est pas nécessaire.
  • Appelez printf uniquement lorsque vous terminez un octet (pas inutilement pour tous les bits).
  • Fonctionne pour n’importe quel type.
  • Fonctionne avec un peu et une grande endianness (utilise GCC #defines pour vérifier).
  • Utilise typeof () qui n’est pas standard mais qui est largement défini.
 #include  #include  #include  #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; } 

Sortie

 $ ./printb 11111111 11111111 00000000 11111111 00000000 00000000 00000000 11111111 01000100 00000000 00000000 00000000 01000100 01000100 00010001 11111111 00000001 00000000 01000011 

J'ai utilisé une autre approche ( bitprint.h ) pour remplir un tableau avec tous les octets (sous forme de chaînes de bits) et les imprimer en fonction de l'octet d'entrée / index. Ça vaut le coup de regarder.

Ma solution:

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

Basé sur la suggestion de @ ideasman42 dans sa réponse, il s’agit d’une macro qui fournit des int8 , 16 , 32 et 64 , réutilisant la macro INT8 pour éviter les répétitions.

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

Cela produit:

 My Flag 0001011011100001001010110111110101111000100100001111000000101000 

Pour plus de lisibilité, vous pouvez modifier: #define PRINTF_BINARY_SEPARATOR en #define PRINTF_BINARY_SEPARATOR "," ou #define PRINTF_BINARY_SEPARATOR " "

Cela va sortir:

 My Flag 00010110,11100001,00101011,01111101,01111000,10010000,11110000,00101000 

ou

 My Flag 00010110 11100001 00101011 01111101 01111000 10010000 11110000 00101000 
 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); } } 

devrait fonctionner – non testé.

 /* 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" */ 

Suivant va vous montrer la disposition de la mémoire:

 #include  #include  #include  using namespace std; template ssortingng binary_text(T dec, ssortingng byte_separator = " ") { char* pch = (char*)&dec; ssortingng 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; } 

Voici une petite variante de la solution de paniq qui utilise des modèles pour permettre l’impression d’entiers 32 et 64 bits:

 template inline std::ssortingng 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::ssortingng(b); } 

Et peut être utilisé comme:

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

Voici le résultat:

  0x1e127ad: 00000001111000010010011110101101 0x2e0b04ce0: 0000000000000000000000000000001011100000101100000100110011100000 

Je veux juste poster ma solution. Il est utilisé pour obtenir des zéros et ceux d’un octet, mais l’appel de cette fonction peu de fois peut être utilisé pour des blocs de données plus importants. Je l’utilise pour des structures de 128 bits ou plus. Vous pouvez également le modifier pour utiliser size_t comme paramètre d’entrée et pointeur sur les données que vous souhaitez imprimer, afin qu’il puisse être indépendant de la taille. Mais ça marche pour moi de quitter comme il est.

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

Here’s how I did it for an 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 ); } 

A small utility function in C to do this while solving a bit manipulation problem. This goes over the ssortingng checking each set bit using a mask (1<

 void printSsortingngAsBinary(char * input) { char * temp = input; int i = 7, j =0;; int inputLen = strlen(input); /* Go over the ssortingng, 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"); } } 

Yet another approach to print in binary: Convert the integer first .

To print 6 in binary, change 6 to 110 , then print "110" .

Bypasses char buf[] issues.
printf() format specifiers, flags, & fields like "%08lu" , "%*lX" still readily usable.
Not only binary (base 2), this method expandable to other bases up to 16.
Limited to smallish integer values.

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