Copy structure to clipboard

I have a structure:

struct data{ int num1; int num2; int num3; int num4; } 

Now I can convert the individual elements and then put them in a buffer, but I want to copy the entire structure to a buffer (char buffer [sizeof (data)]).

Is there any way to copy?

+4
source share
5 answers

In my comment on this answer ,

I am trying to copy this structure to flash [memory chip]. And the Flash reader / writer API passes the string. - Punit 2 hours ago

You will find that you have an XY problem - you are asking how to implement your idea of ​​a solution, not how to solve your problem. You really do not want to copy the structure to the buffer, you want to write data in your structure to Flash using an API that requires the char * argument.

Others noted that memcpy will do what you want. But they all include memory allocation for this buffer in RAM. Using these approaches will work, but they will waste time and memory. Assuming your Flash API has a function:

 int WriteBlock(int address, char *data, int length); 

and you saved your structure in a variable called data_var , you can use your API like memcpy:

 int success = WriteBlock(my_address, (char *) &data_var, sizeof(struct data) 

To be clearer and avoid casting, you can wrap this in a union:

 union { struct data{ int num1; int num2; int num3; int num4; }; char data_arr[sizeof(struct data)]; }; 

This will allow you to call it more traditional syntax.

Note that both methods (and memcpy!) Can fail if you have an non-contiguous structure. For example, perhaps your structure is as follows:

 struct data{ int num1; char num2; long num3; short num4; } 

If you use anything other than an 8-bit system, such a structure will probably (depending on your architecture) contain spaces. For example, if num1 is 0x12345678, num2 is 0x9A, num3 is 0xBCDEF0123456789A, and num4 is 0xBCDE, you might have the following: it is assumed that your memory has zero initialization, and for clarity - in big-endian format):

  / * 8-bit * /
     0x1234 5678 9ABC DEF0 1234 5678 9ABC DE00
     / * 16-bit * /
     0x1234 5678 009A BCDE F012 3456 789A BCDE
     / * 32-bit * /
     0x1234 5678 0000 0000 0000 009A BCDE F012 3456 789A 0000 0000 0000 BCDE

In this case, you will need to use something uglier, like the following function:

 int fillDataBuffer(struct data d, char *buffer, int len) { int i, j = 0; for (i = sizeof(d.num1) - 1; i >= 0 && j < len; i--, j++) { buffer[j] = (char) (d.num1 >> i); } for (i = sizeof(d.num2) - 1; i >= 0 && j < len; i--, j++) { buffer[j] = (char) (d.num2 >> i); } for (i = sizeof(d.num3) - 1; i >= 0 && j < len; i--, j++) { buffer[j] = (char) (d.num3 >> i); } for (i = sizeof(d.num4) - 1; i >= 0 && j < len; i--, j++) { buffer[j] = (char) (d.num4 >> i); } if (j >= len) { /* Error! The buffer wasn't big enough. */ return 0; } else { return 1; } } 

or the macro #pragma pack() , but this can make calculations using the structure slower, and you are likely to pack it when you do buffering.

+6
source

memcpy can do it

Microsoft systems can use memcpy_s to automatically check sizes

You also need to know the pointers inside the struct data .

 struct data { int num1; char* name; } 

the contents of the memory pointed to by char* name will not be copied by memcpy. You will need some kind of serialization which is a little more complicated.

Here is the correct code. It copies the data and then displays the result

 struct data{ int num1; int num2; int num3; }; int main(int argc, char** argv) { data my_data; my_data.num1 = 64; my_data.num2 = 65; my_data.num3 = 66; char buffer[20]; memcpy(buffer, &my_data, sizeof(data)); data copy_data; memcpy(&copy_data, buffer, sizeof(data)); printf("the numbers : %d - %d - %d \n", copy_data.num1, copy_data.num2, copy_data.mum3); return 0; } 
+5
source

First, you need a semicolon after closing. Secondly, you should use typedefs. Thirdly, you should use custom types (some recommend putting _t after your types, but this actually violates the C standard because such names are reserved). Fourth, you need a value of this type to copy. Given all this:

 typedef struct{ int num1; int num2; int num3; int num4; } Data; Data foo = { 1, 2, 3, 4}; char buffer[sizeof foo]; // at least memcpy(buffer, &foo, sizeof foo); 

However, I would question why you really want to copy the structure into a char buffer. You must indicate what you are actually trying to achieve, because there is a good chance that there is a better way to do this.

+1
source

Using memcpy will allow you to copy the entire structure to the buffer. For example, the contents of "ob1" are copied to the "buffer" in the following code:

  #include <stdio.h> #include <stdlib.h> #include <string.h> struct data{ int num1; int num2; int num3; int num4; }; int main() { struct data ob1; struct data *buffer = (struct data *)malloc(sizeof(struct data)); if(buffer == NULL) { printf("Memory allocation failed\n"); return; } ob1.num1 = 1; ob1.num2 = 2; ob1.num3 = 3; ob1.num4 = 4; memcpy(buffer, &ob1, sizeof(struct data)); } 
+1
source

The answer above will only work if the size of the structural elements is the same size (provided that you use a 32-bit processor and compiler). Thus, ints will be 32 bits each, but if your structure contains, for example, char, as well as ints, then the compiler will probably select char up to 32 bits for data alignment purposes.

You can try sprintf for each of the elements in the structure and give each element the correct size when loading each element in the char buffer.

Or you can simply load the buffer element by element, using the size increment of the index to the correct number of bytes for each element for each write to the buffer. Long, but possibly more efficient id resources are limited, and data is large.

0
source

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


All Articles