copying integers from char array depending on number of bytes in C - c

I have one character array of 8 bytes containing integer values. I need to copy the 1 byte to one integer variable, next 4 bytes to different integer variable, next 3 bytes to another integer variable.
I have used "memcpy" but the results are not proper.
My try:
unsigned char bytes[8];
int Data1 = 32769;
int Data2 = 65535;
int logic1 = 0;
int logic2 = 0;
int logic3 = 0;
memcpy(&bytes[0], &Data1, sizeof(Data1));
memcpy(&bytes[4], &Data2, sizeof(Data2));
//Value of bytes[] array after this operation is
//bytes[0] = 1
//bytes[1] = 128
//bytes[2] = 0
//bytes[3] = 0
//bytes[4] = 255
//bytes[5] = 255
//bytes[6] = 0
//bytes[7] = 0
memcpy(&logic1,&bytes,1);
memcpy(&logic2,&bytes + 1,4);
memcpy(&logic3,&bytes + 5,1);
My output should be :
logic1 = bytes[0]
logic2 = bytes[1] to bytes[4]
logic3 = bytes[5] to bytes[7]

I think you meant
memcpy( &logic1, &bytes[0], 1 );
memcpy( &logic2, &bytes[1], 4 );
memcpy( &logic3, &bytes[5], 3 );
Note that &bytes is a pointer to the whole array, so &bytes + 1 points beyond the end of the array, and &bytes + 5 is way beyond the end of the array. Hence you get undefined behavior, and unexplainable results.

Related

Please run this code and tell me why got this result

why the result of " (num >> i)& 1 " is 1 for the second loop?
main() {
char num = 5 ;
int i , count = 0 ;
for(i=0;i<8;i++){
if ((num >> i)& 1 )
count++;
}
printf("%d", count);
}
For starters pay attention to that the variable num itself is not being changed within the for loop
for(i=0;i<8;i++){
if ((num >> i)& 1 )
count++;
}
Its binary representation is
00000101
(Note take into account that the declaration
char num = 5 ;
differs from the declaration
char num = '5' ;
end note.)
In the first iteration of the loop when i is equal to 0 the shift operator has no effect so the if statement evaluates to logical true and the variable count will be incremented.
The variable count also will be incremented when i is equal to 2.
So as a result you will get that count is equal to 2 because in the internal representation of the variable num only two bits are set..
To make it more clearer rewrite the program the following way
#include <stdio.h>
int main(void)
{
char num = 5 ;
int count = 0 ;
for ( int i = 0; i < 8; i++ )
{
int result = (num >> i)& 1;
printf( "i = %d, result = %d\n", i, result );
if ( result ) count++;
}
printf( "\ncount = %d\n", count );
}
The program output is
i = 0, result = 1
i = 1, result = 0
i = 2, result = 1
i = 3, result = 0
i = 4, result = 0
i = 5, result = 0
i = 6, result = 0
i = 7, result = 0
count = 2
In fact the output from top to bottom shows the internal representation of the variable num starting from its less significant bit to the most significant bit.

What does ((short *)((((char *)(&arr[1]))+8))[3]=100; do?

...
int arr[5];
arr[3]=128;
((short *)((((char *)(&arr[1]))+8))[3]=100;
...
Above is part of a pretentious code.
What does
((short *)((((char *)(&arr[1])) + 8))[3] = 100
the line do? The following is my thought assuming char is 1 byte and int is 4 byte.
arr will look like arr[0], arr[1], arr[2], arr[3], arr[4] in memory with each 4 bytes. &arr[1] points to arr[1]. (char *)(&arr[1]) is treating arr[1] value 4 bytes as char each of 1 byte.
What is the function part of (char *)(&arr[1]) and ((char *)(&arr[1])) + 8 individually?
((short *)((((char *)(&arr[1])) + 8))[3] = 100
&arr[1]: is the address of the second int in arr (1*sizeof(int) from start).
((char *)(&arr[1])) : converts int address to a char address
(((char *)(&arr[1])) + 8) : adds 8 bytes to the char address
((short *)((((char *)(&arr[1])) + 8)): converts the char address to a short address
((short *)((((char *)(&arr[1])) + 8))[3]: treats the short address as a beginning of an array of storts and goes to the third element in this array (3 * sizeof(short) bytes).
((short *)((((char *)(&arr[1])) + 8))[3] = 100; : assigns 100
*((short*)(((char*)arr) + 1*sizeof(int) + 8 + 3*sizeof(short))) = 100;
The size of an int varies depending on processors but is often 4 bytes.
The size of a short varies depending on processors but is often 2 bytes.
*((short*)(((char*)arr) + 18)) = 100;
Let's split it up (ignoring unneeded brackets):
int* p0 = &arr[1];
char* p1 = (char *)p0;
char* p2 = p1 + 8;
short* p3 = (short *)p2;
p3[3] = 100;
Your arr array has 5 times an 4-bytes integer = a block of 20 bytes.
p0 points to the address of the second integer, so byte at index 4.
p1 stores p0 as address to chars / bytes.
p2 increases the value of p1 by 8 (chars) = points to byte at index 12.
p3 changes p2 to pointer type of 2-bytes (short) integer.
Last line points to fourth short (integer) value which means an address increment by 3 * 2 bytes = now we're at byte index 18 of arr. There we assign value 100 as the last two bytes (index 18 & 19) of our available memory.
In short:
((short *)arr)[9] = 100;
Full example:
#include <stdio.h> // printf
int main(void) {
// Initialize zero-filled memory
int arr[5] = {0};
// Write value 100 to last 2 bytes
((short*)arr)[9] = 100;
// Print memory
for (int i = 0; i < sizeof(arr) / sizeof(arr[0]); i++)
printf("%d ", arr[i]); // 0 0 0 0 6553600
}
it can be translated to:
short *ptr = (short *)(arr + 1 + 8 / sizeof(*arr)); // or &arr[1 + 8 / sizeof(*arr)]
ptr[3] = 100;

Divide a string of 32 into 4 8 hex in c

community, I have little experience with C and I am on the learning curve right now.
I am working on a little project that involves dividing a 32-char string into 4 strings of 8 chars each in C.
The 32-char string should resemble a 32-bit instruction. Those "32 bits" are divided into 4 "8-bit" strings that I want to print out as Hex. The code below is what I got so far. The data types I am using are the ones I am using in the rest of my code. I intend to feed the unsigned char t variable into an Substitution Box program that will give me equivalent of that t char from the S-Box lookup table.
The code below seems to me like it should work
unsigned char inst[] = "10101010101010101111111100111101";
unsigned char in[8];
for (int i = 0; i < 33; i++){
if (i%8 == 0 && i != 0) {
unsigned char t = (unsigned char) strtol(in, NULL, 2);
printf("%x \n", t);
}
in[i%8] = inst[i];
printf("%c ", in[i%8]);
}
but the output looks like this:
1 0 1 0 1 0 1 0 3d
1 0 1 0 1 0 1 0 3d
1 1 1 1 1 1 1 1 3d
0 0 1 1 1 1 0 1 3d
I can see that in[i%8] = inst[i]; line is reading the chars from inst[] correctly, but the
if (i%8 == 0 && i != 0) {
unsigned char t = (unsigned char) strtol(in, NULL, 2);
printf("%x \n", t);
}
conditional statement prints the wrong hex.
The output should look like something like this
1 0 1 0 1 0 1 0 aa
1 0 1 0 1 0 1 0 aa
1 1 1 1 1 1 1 1 ff
0 0 1 1 1 1 0 1 3d
Any help would be appreciated.
Problems with the current code:
"4 strings of 8 chars each" is char in[4][8+1]; and not char in[8]. You need room for null termination.
32 bits means iterate from 0 to 31, not from 0 to 32.
There's no need to copy byte per byte. It's slow and makes everything needlessly complicated.
This seems to be the requirements:
Split the original string in 4 sub strings.
Convert each sub string to an integer.
Display the result as hex
In which case you can simply iterate 4 times over the input string:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int main (void)
{
const char* inst = "10101010101010101111111100111101";
char in [4][8+1];
puts("Bin Hex");
for(size_t i=0; i<4; i++)
{
memcpy(in[i], &inst[i*8], 8);
in[i][8] = '\0';
unsigned long val = strtoul(in[i], NULL, 2);
printf("%.8s %.2lX\n", in[i], val);
}
}
Output:
Bin Hex
10101010 AA
10101010 AA
11111111 FF
00111101 3D
The problem is your in is not NUL terminated.
Thus passing in to strol invokes the undefined behavior.
Do as below.
unsigned char in[9]; //+1 to hold the NUL char.
....
if (i%8 == 0 && i != 0) {
in[8] = '\0'; //NUL terminate the string.
unsigned char t = (unsigned char) strtol(in, NULL, 2);
printf("%x \n", t);
}

Not getting the expected results at pointer increment

Pointer increment not giving the right value, it points to indeterminate address.
Want to know why *p++= <value> not pointing to the value I want instead it points to something else
My code:
void run_exe() {
int i;
uint8_t buf[20] = {"0"};
uint8_t *p = NULL;
uint8_t tx_buf[4] = {1,1,1,1};
p = buf;
*p++ = 0x14;
*p++ = 0x20;
*p++ = 0x30;
*p++ = 0x40;
*p++ = 0x50;
*p++ = 0x60;
memcpy( p+6, tx_buf, sizeof(tx_buf));
// ARRAY_SIZE: is the macro just my array length.
for (i = 0; i < ARRAY_SIZE(buf); i++) {
printf("%d ", *(p+i));
}
}
I'm printing the decimal value of HEX but at least I'm expecting the correct value but I get indeterminate value.
I'm expecting the output like this.
14 20 30 40 50 60 1 1 1 1 0 0 0 0 0 0 0 0 0
Output:
0 0 0 0 0 0 1 1 1 1 0 0 0 0 255 127 0 0 0
You need an auxiliary pointer,
uint8_t *ptr;
p = buf;
ptr = p;
*p++ = 0x14;
and so on, because the ++ will modify the pointer's value.
Then,
for (i = 0; i < ARRAY_SIZE(buf); i++) {
printf("%d ", ptr[i]);
}
The ++ post-increment or pre-increment operator, makes the pointer p point to p + 1 after the expression is evaluated, so your p is NOT pointing to buf when you attempt to print it.
EDIT: Of course you can just do this too,
for (i = 0; i < ARRAY_SIZE(buf); i++) {
printf("%d ", buf[i]);
}
but I think the original answer explains the reason which is the important thing.
EXTRA: Also, I am 99.9% sure that this is wrong
uint8_t buf[20] = {"0"};
you meant,
uint8_t buf[20] = {0};
your compiler might be showing you a warning for this initialization which is faulty, because "0" has pointer type and even though it's convertible to a integer type, it mostly certainly doesn't fit a uint8_t so you have a overflow issue there.

Exam Q&A that I don't understand [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 8 years ago.
Improve this question
The following code prints out 5. Can someone explain it to me? I think I am mostly confused about the math; for example, using '0' instead of 0 and how I can do that math on paper...
#include <stdio.h>
int main (int argc , char * argv [])
{
char * c_pt ;
int n = 0;
if( argc == 2)
{
c_pt = argv [1];
while (* c_pt )
{
if (* c_pt < '0' || * c_pt > '1') break ;
n = n*2 + * c_pt - '0';
c_pt ++;
}
printf ("%d\n", n);
}
}
When you access the characters in a string containing digits you might get the character '0' or '1' for example. But the integer value of '0' is 48 and the integer value of '1' is 49 so if you want to turn them into the integers 0 and 1 for arithmetic you need to substract something. You could subtract 48 but then the next person that reads your code has no idea why you did that. So nornally you subtract the character represented by the value: '0' - '0' = 0 and '1' - '0' = 1
This particular program reads a string containing a binary number from the command line (so the string contains the characters '0' and '1') and converts that binary number to a decimal number by first converting the '0' and '1' at *c_pt to 0 and 1 and then adding it to the decimal number being built in n. It does that by starting with 0 and then on each iteration multiplying the number by two (which just shifts everything left one bit) and then adding the next digit. So if the string contained 10101 it would follow these steps:
number = 0
input = 10101
pointer = ^
number = number*2 + *pointer = 0*2 + ('1'-'0') = 0*2 + 1 = 1 (in binary: 1)
input = 10101
pointer = ^
number = number*2 + *pointer = 1*2 + ('0'-'0') = 1*2 + 0 = 2 (in binary: 10)
input = 10101
pointer = ^
number = number*2 + *pointer = 2*2 + ('1'-'0') = 2*2 + 1 = 5 (in binary: 101)
input = 10101
pointer = ^
number = number*2 + *pointer = 5*2 + ('0'-'0') = 5*2 + 0 = 10 (in binary: 1010)
input = 10101
pointer = ^
number = number*2 + *pointer = 10*2 + ('1'-'0') = 10*2 + 1 = 21 (in binary: 10101)
void main ( void )
{
int a[] = {22, 33,44};
'a' is a static array (or string) of 3 int, 22, 33, and 44.
int *x = a;
'x' is an int pointer, initialized to point to the same static array as 'a'.
printf (" sizeof ( int )=% lu ", sizeof (int ));
Prints the number of bytes [4] required to represent an int type on this system.
printf ("x=%p, x [0]=% d\n", x, x [0]);
Prints the memory address where the int pointer 'x' is currently pointing[0x7fff29af6530],
then also prints the integer value [22] stored in the [4] bytes starting at that address.
(Note: 'x[0]' is the same as '*x').
x = x + 2;
x [0x7fff29af6530]
+2 + 8 (or (2 * 4) or (2 * sizeof(int)))
---- ----------------
new x [0x7fff29af6538]
Advance the pointer 'x' 8 bytes.
The effect on 'x' is that it will now be pointing at its original memory address plus '(2 * sizeof(int))' bytes. 'a[2]' resolves to the same location.
printf ("x=%p, x [0]=% d\n", x, x[0]);
Prints the memory address where the int pointer 'x' is currently pointing [0x7fff29af6538]
then also prints the integer value [44] stored in the [4] bytes starting at that address.
Hence; 'x' now resolves to the same address as '&a[2]'; and '*x' resolves to the same number as 'a[2]'.
}

Resources