Reading characters at bit level

I would like to be able to enter a character from the keyboard and display the binary code for the specified key in the format 00000001, for example.

In addition, I would also like to read the bit in such a way that I can infer if they are true or false.

eg.

01010101 = false,true,false,true,false,true,false,true 

I would post an idea of ​​how I tried to do this myself, but I absolutely do not know, I'm still experimenting with C, and this is my first taste of programming at such a low level.

Thankyou

+4
source share
3 answers

This code is C89:

 /* we need this to use exit */ #include <stdlib.h> /* we need this to use CHAR_BIT */ #include <limits.h> /* we need this to use fgetc and printf */ #include <stdio.h> int main() { /* Declare everything we need */ int input, index; unsigned int mask; char inputchar; /* an array to store integers telling us the values of the individual bits. There are (almost) always 8 bits in a char, but it doesn't hurt to get into good habits early, and in C, the sizes of the basic types are different on different platforms. CHAR_BIT tells us the number of bits in a byte. */ int bits[CHAR_BIT]; /* the simplest way to read a single character is fgetc, but note that the user will probably have to press "return", since input is generally buffered */ input = fgetc(stdin); printf("%d\n", input); /* Check for errors. In C, we must always check for errors */ if (input == EOF) { printf("No character read\n"); exit(1); } /* convert the value read from type int to type char. Not strictly needed, we can examine the bits of an int or a char, but here how it done. */ inputchar = input; /* the most common way to examine individual bits in a value is to use a "mask" - in this case we have just 1 bit set, the most significant bit of a char. */ mask = 1 << (CHAR_BIT - 1); /* this is a loop, index takes each value from 0 to CHAR_BIT-1 in turn, and we will read the bits from most significant to least significant. */ for (index = 0; index < CHAR_BIT; ++index) { /* the bitwise-and operator & is how we use the mask. "inputchar & mask" will be 0 if the bit corresponding to the mask is 0, and non-zero if the bit is 1. ?: is the ternary conditional operator, and in C when you use an integer value in a boolean context, non-zero values are true. So we're converting any non-zero value to 1. */ bits[index] = (inputchar & mask) ? 1 : 0; /* output what we've done */ printf("index %d, value %u\n", index, inputchar & mask); /* we need a new mask for the next bit */ mask = mask >> 1; } /* output each bit as 0 or 1 */ for (index = 0; index < CHAR_BIT; ++index) { printf("%d", bits[index]); } printf("\n"); /* output each bit as "true" or "false" */ for (index = 0; index < CHAR_BIT; ++index) { printf(bits[index] ? "true" : "false"); /* fiddly part - we want a comma between each bit, but not at the end */ if (index != CHAR_BIT - 1) printf(","); } printf("\n"); return 0; } 

You do not need three loops - you could combine them together if you want, and if you only do one of two types of output, then you will not need an array, you can just use each when you mask it. But I think this keeps things separate and hopefully easier to understand.

+3
source

This is probably not the safest way - do not check the health / size / type, but it should still work.

 unsigned char myBools[8]; char myChar; // get your character - this is not safe and you should // use a better method to obtain input... // cin >> myChar; <- C++ scanf("%c", &myChar); // binary AND against each bit in the char and then // cast the result. anything > 0 should resolve to 'true' // and == 0 to 'false', but you could add a '> 1' check to be sure. for(int i = 0; i < 8; ++i) { myBools[i] = ( (myChar & (1 << i) > 0) ? 1 : 0 ); } 

This will give you an array of unsigned characters - 0 or 1 (true or false) - for the character.

+4
source

It is often safer to use unsigned types to set bits, because shifts with negative values ​​have an implementation-dependent effect. A simple char can be either signed or unsigned (traditionally it is not signed on MacIntosh platforms, but signed on a PC). Therefore, first enter the character in the unsigned char type.

Then your friends are bitwise logical operators ( & , | , ^ and ~ ) and shift operators ( << and >> ). For example, if your character is in the variable x , then to get the 5th bit you simply use: ((x >> 5) & 1) . The shift operators move the value to the right, discarding the five lower bits and moving the bit, you are interested in the "low position" (it is also the "most right"). The bitwise AND with 1 just sets all other bits to 0, so the resulting value is either 0 or 1, which is your bit. Please note that I start from scratch, not from scratch.

If you assume that your characters have 8 bits, you can write your code as:

 unsigned char x = (unsigned char)your_character; int i; for (i = 7; i >= 0; i --) { if (i != 7) printf(","); printf("%s", ((x >> i) & 1) ? "true" : "false"); } 

You may notice that since I am the number of bits from right to left, but you want to output from left to right, the loop index should decrease.

Please note that according to the C standard, unsigned char has at least eight bits, but may have more (currently only a few built-in DSPs have characters that are not 8-bit). To be more secure, add this next to the beginning of your code (as a top-level declaration):

 #include <limits.h> #if CHAR_BIT != 8 #error I need 8-bit bytes! #endif 

This will prevent successful compilation if the target system proves to be one of those special built-in DSPs. In the note to the note, the term “byte” in the C standard means “elementary memory block that corresponds to an unsigned char value”, so in C-talk a byte can have more than eight bits (a byte is not always an octet). This is a traditional source of confusion.

+4
source

Source: https://habr.com/ru/post/1300083/


All Articles