There are numerous ways to do this. The following outputs a nice chart of printable characters giving the value for each character in ASCII, decimal, hex and binary, e.g.
#include <stdio.h>
#include <limits.h>
/* CHAR_BIT */
#ifndef CHAR_BIT
#define CHAR_BIT 8
#endif
int main (void) {
char c = 0; /* character */
int i = 0; /* int loop counter */
printf ("\nchar | int | hex | binary\n");
printf ("-----+-------+--------+---------\n");
for (c = 32; c <= 126; c++) { /* for each char in printable range */
/* output the character, decimal, hex and binary */
printf (" %c | %3d | 0x%02x | ", c, c, c);
for (i = sizeof (c) * CHAR_BIT - 1; i >= 0; i--) /* for each bit */
printf ("%d", ((c >> i) & 0x1) ? 1 : 0); /* output 0/1 */
putchar ('\n'); /* output \n */
}
putchar ('\n');
}
Example Use/Output
$ ./bin/bin_ascii
char | int | hex | binary
-----+-------+--------+---------
| 32 | 0x20 | 00100000
! | 33 | 0x21 | 00100001
" | 34 | 0x22 | 00100010
# | 35 | 0x23 | 00100011
$ | 36 | 0x24 | 00100100
% | 37 | 0x25 | 00100101
& | 38 | 0x26 | 00100110
' | 39 | 0x27 | 00100111
( | 40 | 0x28 | 00101000
) | 41 | 0x29 | 00101001
* | 42 | 0x2a | 00101010
+ | 43 | 0x2b | 00101011
, | 44 | 0x2c | 00101100
- | 45 | 0x2d | 00101101
. | 46 | 0x2e | 00101110
/ | 47 | 0x2f | 00101111
0 | 48 | 0x30 | 00110000
1 | 49 | 0x31 | 00110001
2 | 50 | 0x32 | 00110010
3 | 51 | 0x33 | 00110011
4 | 52 | 0x34 | 00110100
5 | 53 | 0x35 | 00110101
6 | 54 | 0x36 | 00110110
7 | 55 | 0x37 | 00110111
8 | 56 | 0x38 | 00111000
9 | 57 | 0x39 | 00111001
<snip>
p | 112 | 0x70 | 01110000
q | 113 | 0x71 | 01110001
r | 114 | 0x72 | 01110010
s | 115 | 0x73 | 01110011
t | 116 | 0x74 | 01110100
u | 117 | 0x75 | 01110101
v | 118 | 0x76 | 01110110
w | 119 | 0x77 | 01110111
x | 120 | 0x78 | 01111000
y | 121 | 0x79 | 01111001
z | 122 | 0x7a | 01111010
{ | 123 | 0x7b | 01111011
| | 124 | 0x7c | 01111100
} | 125 | 0x7d | 01111101
~ | 126 | 0x7e | 01111110
Let me know if you have any questions about the logic.