Function that reset the 8th bit of the string? - c

I am trying make a code that resets the 8th bit of the string. I have made it work, but I believe it is not still correct. Here is the code:
#include <stdio.h>
#include <stdlib.h>
void make7bit(unsigned char *s, unsigned int n)
{
int i = 0;
int x =0;
while(x <n)
{
if(*s |= (1 << 7)) //it still works, whatever I have 1 << 7 or 1 << 3
*s = '0';
i++;
x++;
}
printf("%s", s);
return NULL;
}
int main()
{
char A[] ={"11111111"};
int n = 8;
make7bit(A, n);
return 0;
}
I dont understand the line if(*s |= (1 << 7)), because whatever it is 1 << 7 or something else (for example 1 << 3) it still works, or at least it reset the last bit of the string. I am quite sure I am doing something wrong here, but what? I think the code is now resetting the last bit of the string and not the 8th one as I would like...
Could someone help me with this one?

1 << 3 is 00001000, 1 << 7 is 10000000.. You're not clearing the 8th bit in any case.
If you want to clear a bit (not setting it), you should:
*s &= ~(1 << 7);

Your question is unclear. What does it means '8th bit of the string'? You should reset 8th bit of every byte? Or something else? Why do you set *s to '0'? Should results for "11111111" and "12345678" be the same? Do you assume usual string, or maybe every char represents one bit?
If you wish to reset 8th bit of every byte, you should use
*s &= 0x7F;
But generally your source contains no any line which corresponts to task described.
Btw, your loop is senseless. You described two loop variables, but never use it; you just patches one byte 8 times in a row.

Your are done the left shift with the value one.
1 << 7
Now the bit is 10000000.
So you are doing the or operation with this value. Here *s value is,
*s=1. Bit position of one is. 00110001.
Because ascii value of 1 is 49.Here you are using the character so the value is taken in ascii. And bit representation for one byte.Now or operation.
00110001
10000000
---------
10110001
So the value is non zero so the if condition works and the position is changed into 0.

Related

Wrong use of state condition [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 9 years ago.
Improve this question
I am using the following code to check if bit number 25 value is 0 or 1:
volatile unsigned int * regAddr;
unsigned int regval;
regAddress = (unsigned int *) 0xD2009010; //This is a valid address of register
regVal = *regAddress; //The return value here is 0xFE008000
if (!(regVal & 0x4000000)) //For the mentioned return value, I thought the condition will be different then 0 and so used '!' to convert the value
the bit is 0;
else
the bit is 1;
This code isn't working properly and I cannot figure out why. Help anyone? Thanks in advance
The sure-way to get the 25th bit is:
if (!(regVal & (1 << 24) ))
Or, if you prefer:
#define BIT_25 (1 << 24) // the first-bit, shifted over 24 more times.
if (!(regVal & BIT_25 ))
Several people raise the point that "bit number 25" is ambiguous, depending on if you consider 0x01 to be the first-bit, or the zeroth-bit.Decide this yourself as is appropriate for your program.But no matter what, 0x4000000 is not right.
Take a look at shift operators:
http://www-numi.fnal.gov/offline_software/srt_public_context/WebDocs/Companion/cxx_crib/shift.html
Something like
if ((yourVal >> 25) & 0x1)
Should do what you want.
For example: Printing the whole number then the 25th and 26th bits:
#include <unistd.h>
#include <stdio.h>
int getBitValue(unsigned int num, unsigned int pos) {
return ((num >> pos) & 0x1);
}
int main() {
unsigned int num = 0xD2009010;
printf("Value = 0x%X\n", num);
write(1, "Binary: ", 8);
for (int i = (sizeof(num) * 8); i >= 0; --i) {
if (getBitValue(num, i))
write(1, "1", 1);
else
write(1, "0", 1);
}
write(1, "\n", 1);
printf("25th bit: %d\nBit at index 25 (26th): %d\n",
getBitValue(num, 24),
getBitValue(num, 25));
return 0;
}
If you are trying to test the 25th bit then 0x4000000 is not the right literal, depending on which bit you consider to be the starting bit then you are testing bit 26 or 27.
Of course instead of using hand calculated literals, the easier way you be to use a bit shift, depending what what you consider the starting bit one of these should do what you need:
if( !(regVal & (1 << 24)) )
or
if( !(regVal & (1 << 25)) )
If your code is exactly what you write, then the bit is ...; is not valid C. If that is the problem, use puts("the bit is ...");
About the condition, you should use if (!(regVal & 0x1000000)). That's the value of 1<<(25-1). (In my understandind 0x1 is first bit and so on)
I assume that the address 0xD2009010 is that of the register you are reading, that the architecture you are using has memory mapped registers (and that you are probably writing a device driver, certainly not an application unless you are writing for vxWorks or DOS ....), then if you want to test bit 25 you should test for 0x2000000 (remember that bits start from 0, so each nibble goes up by 4: 0, 4, 8, etc, after 6 0s you are at bit 24 (this would be 0x1000000). You want 25, so this is 0x2000000.

How to work with individual bits? [duplicate]

This question already has answers here:
Closed 11 years ago.
Possible Duplicate:
Explanation of an algorithm to set, clear and test a single bit
I have an unsigned char. I would like to have bits 2 through 4 (counting from the least significant bit as 0) copied to another unsigned char as the first three bits. For example, in
abcdefgh // a,b,c,d,e,f,g,h are 0 or 1
becomes
00000def
I have tried
unsigned char input, output;
output = (input << 3) >> 5;
which does not work, but
output = (input << 3)
output >>= 5;
does work.
Is there a way in C to accomplish this in one line?
shift it, then mask the rest off:
output = ( input >> 2 ) & 0x07;
This gets only the bits you want then shifts them to the right. It's the opposite approach of #rsaxvc.
output = (input & 28) >> 2;
Try this:
unsigned char input, output;
input = 0x12abcdef;
output = ((input & 0x00fff000) >> 3) & 0x00000fff;
I don't think you can just shift back and forth on the same line and assume every time you shift the space is filled by zeroes, but this may be compiler dependent, if you do this you'll get the right thing guaranteed.
I'm assuming by "first three bits" you mean the 3 least significant bits, which is the leftmost or first 3 bits on little-endian systems.

How to store two different things in one byte and then access them again?

I am trying to learn C for my class. One thing I need to know is given an array, I have to take information from two characters and store it in one bytes. For eg. if string is "A1B3C5" then I have to store A = 001 in higher 3bits and then store 1 in lower 5bits. I have to function that can get two chars from array at a time and print it here is that function,
void print2(char string[])
{
int i = 0;
int length = 0;
char char1, char2;
length = strlen(string);
for ( i = 0; i <length; i= i + 2)
{
char1 = string[i];
char2 = string[i+1];
printf("%c, %c\n", char1, char2);
}
}
but now i am not sure how to get it encoded and then decode again. Can anyone help me please?
Assuming an ASCII character set, subtract '#' from the letter and shift left five bits, then subtract '0' from the character representing the digit and add it to the first part.
So you've got a byte, and you want the following bit layout:
76543210
AAABBBBB
To store A, you would do:
unsigned char result;
int input_a = somevalue;
result &= 0x1F; // Clear the upper 3 bits.
// Store "A": make sure only the lower 3 bits of input_a are used,
// Then shift it by 5 positions. Finally, store it by OR'ing.
result |= (char)((input_a & 7) << 5);
To read it:
// Simply shift the byte by five positions.
int output_a = (result >> 5);
To store B, you would do:
int input_b = yetanothervalue;
result &= 0xE0; // Clear the lower 5 bits.
// Store "B": make sure only the lower 5 bits of input_b are used,
// then store them by OR'ing.
result |= (char)(input_b & 0x1F);
To read it:
// Simply get the lower 5 bits.
int output_b = (result & 0x1F);
You may want to read about the boolean operations AND and OR, bit shifting and finally bit masks.
First of all, one bit can only represent two states: 0 and 1, or TRUE and FALSE. What you mean is a Byte, which consists of 8 bits and can thus represent 2^8 states.
Two put two values in one byte, use logical OR (|) and bitwise shift (<< and >>).
I don't post the code here since you should learn this stuff - it's really important to know what bits and bytes are and how to work with them. But feel free to ask follow up question if something is not clear to you.

How to form a character byte by assigning values to each of the bits?

I have a C function which accepts a character. I need to extract as well insert bits into that character. I am clear with the extraction part. Can anyone give me an idea of how to insert values to bits?
Pretty vague question, I would suggest you brush up on bitwise operators. This should point you in the right direction.
http://www.cprogramming.com/tutorial/bitwise_operators.html
Since you requested for idea and not exact implementation:
Here is what you can do,
Iterate over each bit and set it as required.
You can set the nth bit (0 indexed as follows)
byteVal = byteVal | (1<<N);
Say you want to check the nth bit of a char:
int checkBit(char c, int n) {
return c & (1 << n);
}
To set the nth bit:
void setBit(char *c, int n) {
*c |= 1 << n;
}
If you want to set the Nth bit in a character to 1, you need to OR it with the value 1 shifted to the left by N positions:
c |= 1 << N;
Sure, simply resort to binary operations. The following function should do exactly what you want, but with a simple interface:
char set8 (char ch, int index) {
if (index >= 1 && index <= 8) {
return (char)(ch | (1 << index - 1));
}
return ch;
}
int n = 0;
set8(n, 1); // Returns 1
set8(n, 2); // Returns 2
set8(n, 3); // Returns 4
...
set8(n, 9); // Returns n (0)
The function uses bitwise-OR to toggle the specified bit. If the index specified is outside the range of a byte (8 bits), then it simply returns the character passed in.

Easy way to convert a string of 0's and 1's into a character? Plain C

I'm doing a steganography project where I read in bytes from a ppm file and add the least significant bit to an array. So once 8 bytes are read in, I would have 8 bits in my array, which should equal some character in a hidden message. Is there an easy way to convert an array of 0's and 1's into an ascii value? For example, the array: char bits[] = {0,1,1,1,0,1,0,0} would equal 't'. Plain C
Thanks for all the answers. I'm gonna give some of these a shot.
A simple for loop would work - something like
unsigned char ascii = 0;
unsigned char i;
for(i = 0; i < 8; i++)
ascii |= (bits[7 - i] << i);
There might be a faster way to do this, but this is a start at least.
I wouldn't store the bits in an array -- I'd OR them with a char.
So you start off with a char value of 0: char bit = 0;
When you get the first bit, OR it with what you have: bit |= bit_just_read;
Keep doing that with each bit, shifting appropriately; i.e., after you get the next bit, do bit |= (next_bit << 1);. And so forth.
After you read your 8 bits, bit will be the appropriate ASCII value, and you can print it out or do whatever with it you want to do.
I agree with mipadi, don't bother storing in an array first, that's kind of pointless. Since you have to loop or otherwise keep track of the array index while reading it in, you might as well do it in one go. Something like this, perhaps?
bits = 0;
for ( i = 0; i < 8; ++i ) {
lsb = get_byte_from_ppm_somehow() & 0x01;
bits <<= 1 | lsb;
}
As long as the bit endian is correct, this should work and compile down pretty small.
If the bit endian is backwards then you should be able to change the initial value of mask to 1, the mask shift to <<= , and you might need to have (0x0ff & mask) as the do{}while conditional if your compiler doesn't do what it's supposed to with byte sized variables.
Don't forget to do something for the magic functions that I included where I didn't know what you wanted or how you did something
#include <stdint.h> // needed for uint8_t
...
uint8_t acc, lsb, mask;
uint8_t buf[SOME_SIZE];
size_t len = 0;
while (is_there_more_ppm_data()) {
acc = 0;
mask = 0x80; // This is the high bit
do {
if (!is_there_more() ) {
// I don't know what you think should happen if you run out on a non-byte boundary
EARLY_END_OF_DATA();
break;
}
lsb = 1 & get_next_ppm_byte();
acc |= lsb ? mask : 0; // You could use an if statement
mask >>= 1;
} while (mask);
buf[len] = acc; // NOTE: I didn't worry about the running off the end of the buff, but you should.
len++;
}

Resources