The following task is from an exam I took in engineering school (mechanical engineering):
You get an array unsigned char buffer[128]; used to read data from a source byte by byte, containing data of the structure:
struct Pixel {
unsigned char x;
unsigned char y;
unsigned char greyValue;
};
The task is: Create an instance of a pixel and copy the data content from the header of the buffer using "memcpy".
My aproach does not seem to work:
#include <stdio.h>
#include <string.h>
struct Pixel {
unsigned char x;
unsigned char y;
unsigned char greyValue;
};
int main()
{
unsigned char buffer[128] = {2,4,44};
struct Pixel singlePixel;
memcpy(singlePixel, buffer, 3);
printf("singlePixel.x = %d\n", singlePixel.x);
printf("singlePixel.y = %d\n", singlePixel.y);
printf("singlePixel.greyValue = %d\n", singlePixel.greyValue);
return 0;
}
I would expect that singlePixel.x = 2, singlePixel.y = 4 and singlePixel.greyValue = 44.
When debugging I get the error: incompatible type for argument 1 of ‘memcpy’
I'm also not at all sure if my approach is up to the task, since I don't understand exactly how this should works with the buffer...
I have many programs where structs are defined. And each time, I have to create a function to print the members. For example,
typedef struct {
char name[128];
char address[1024];
int zip;
} myStruct;
void printMyStruct(myStruct myPeople) {
printf("%s\n",myPeople.name);
printf("%s\n",myPeople.address);
printf("%d\n",myPeople.zip);
}
int main()
{
myStruct myPeople={"myName" , "10 myStreet", 11111};
printMyStruct(myPeople);
}
I know that reflection is not supported in C. And so, I write these printing functions for each struct I defined.
But, I wonder if it exists any tricks to generate automatically these printing functions. I would understand that I have to modify a little bit these functions. But, if a part of the job is done automatically, it would be great.
(This example is simple, sometimes struct are nested or I have array of structs or some fields are pointers, ...)
You can of-course print structs, but expect a lot of non-readable output:
#include <stdio.h>
#include <ctype.h>
struct example {
int x;
int y;
char c;
};
#define NOT_PRINTABLE "Not Printable"
void print_structure(const char *structure, size_t size) {
for (size_t i = 0; i < size; i++) {
printf("%ld)\t%.2X: %.*s\n", i, structure[i],
(isprint(structure[i]) ? 1 : sizeof(NOT_PRINTABLE) - 1),
(isprint(structure[i]) ? &structure[i] : NOT_PRINTABLE));
}
}
int main(int argc, char **argv) {
struct example a;
a.x = 5;
a.y = 6;
a.c = 'A';
print_structure((char *)&a, sizeof(struct example));
return 0;
}
But the issue is that, it will print the structs as it is represented in memory. So 4 byte (32 bit) integer 1 will be represented with 4 bytes, not the char '1'.
And due to the way pointers work, you cannot make out if a member is a pointer or a non-pointer.
Another issue is that structures have padding to help with alignment, and better/efficent use of memory. So you would see a lot of 0x00 in the middle.
Remember that C is a compiled language.
let's consider to use https://copilot.github.com/. it's great.
this is what i have with copilot
typedef struct {
char name[128];
char address[1024];
int zip;
} myStruct;
//print struct myStruct >> auto generate by codepilot after you type a comment `print struct myStruct`
void printStruct(myStruct *s) {
printf("name: %s\n", s->name);
printf("address: %s\n", s->address);
printf("zip: %d\n", s->zip);
}
I'm making a program that returns a struct containing an array, but the elements in the array are completely wrong. I keep searching for an answer on this site, Google, and even Bing and nothing. The best I can find are answers like this:
Functions can't return arrays in C.
However, they can return structs. And structs can contain arrays...
from How to make an array return type from C function?
Now, how do I fix this without the use of pointers?
#include <stdio.h>
#include <math.h>
#include <stdlib.h>
#include <ctype.h>
struct Codes{
int as;
int a[];
};
struct Codes create(int as){
int a[as];
for(int j = 0;j<as;j++)
a[j]=j+1;
struct Codes c;
c.as = as;
c.a[c.as];
for(int i=0; i<as; i++)
c.a[i] = a[i];
for(int i=0; i<as; i+=1)
printf("%d \n", c.a[i]);
return c;
}
int main(int argc, char **argv) {
struct Codes cd;
int as = 4;
cd = create(as);
for(int i=0; i<4; i+=1)
printf("%d \n", cd.a[i]);
}
Actual output:
1
2
3
4
0
0
2
-13120
Expected output:
1
2
3
4
1
2
3
4
structs with flexible value are not meant to be manipulated by value, only by pointer.
You cannot return a struct with a flexible member by value, because C does not know how many items it needs to allocate to the return value, and how many bytes it needs to copy.
Allocate your struct in dynamic memory using malloc of sufficient size, copy your data into it, and return a pointer to the caller:
struct Codes *c = malloc(sizeof(struct Codes)+as*sizeof(int));
c->as = as;
for (int i = 0 ; i != as ; i++) {
c->a[i] = i+1;
}
return c;
Change your function to return a pointer; make sure the caller frees the result.
In your function, struct Codes create(int as), the struct Codes c; is allocated on the stuck, so the memory is no longer valid once the function returns...
...It is true that the core struct is copied in the return value... but the variable array length c.a isn't part of the struct (it's a memory "trailer" or "footer") and isn't copied along with the return value.
Either:
allocate the struct and pass it to a struct Codes create(struct Codes *dest, int as) function; OR
make the struct array fixed in size struct Codes{ int as; int a[4]; };
Good luck.
Is it possible to create a struct containing two dynamically size arrays in c?
I have something like this:
#define MAX_DATA 512
struct Address {
int id;
int set;
char name[MAX_DATA];
char email[MAX_DATA];
};
I'd like MAX_DATA to be defined at run time.
I have seen the struct hack:
How to include a dynamic array INSIDE a struct in C?
But I think this only works for one field per struct?
This code is from http://c.learncodethehardway.org/book/ex17.html
The extra credit section near the bottom of that page contains the bit about changing the sizes to be dynamic.
I once did this:
struct Thing {
int Number;
char *MoreBytes;
char Bytes[]
}
Thing *MakeThing(int nBytes, int nMoreBytes)
{
Thing *th = malloc(sizeof(Thing) + nBytes + nMoreBytes);
// Error checking is for grrrlz.
th->Number = 42;
th->MoreBytes = th->Bytes + nBytes;
return th;
}
Thus the array th->Bytes actually holds both "arrays", and the pointer th->MoreBytes tells us
where one array ends and another begins.
It works (at least for GCC 4.7.2) if you put your struct Address definition in a function, like this:
#include <stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int len = atoi(argv[1]);
struct Address {
int id;
char name[len];
int set;
char email[len];
};
printf("sizeof(struct Address) = %zu\n", sizeof(struct Address));
exit(EXIT_SUCCESS);
}
Testing:
$ ./a.out 10
sizeof(struct Address) = 32
$ ./a.out 20
sizeof(struct Address) = 48
struct Address
{
int id;
int set;
char *name;
char *email;
};
Now in the main() function, Use some variable, lets say len to store length of the array, and dynamically allocate required memory using malloc().
int len;
struct Address Add;
printf("Enter the lenght of the array you want?");
scanf("%d",&len);
Add.name=(char *)malloc(len);
Add.email=(char *)malloc(len);
otherwise you can add len as the member of the struct Address
struct Address
{
int id;
int set;
int len;
char *name;
char *email;
};
Now in main()
struct Address Add;
printf("Enter the lenght of the array you want?");
scanf("%d",&Add.len);
Add.name=(char *)malloc(Add.len);
Add.email=(char *)malloc(Add.len);
You can do this using the struct hack, now known as a flexible array. It just requires you to pack both arrays into the flexible part of the struct.
Suppose that you want the arrays to be of length N and M respectively. Then allocate a flexible array as if you were allocating a single array of length N+M. Then use indices 0..N-1 for the first array, and indices N..N+M-1 for the second array.
Suppose I have this struct (which incidentally contain bit-fields, but you shouldn't care):
struct Element {
unsigned int a1 : 1;
unsigned int a2 : 1;
...
unsigned int an : 1;
};
and I want to access the i'th member in a convenient way. Let's examine a retrieval solution.
I came up with this function:
int getval(struct Element *ep, int n)
{
int val;
switch(n) {
case 1: val = ep->a1; break;
case 2: val = ep->a2; break;
...
case n: val = ep->an; break;
}
return val;
}
But I suspect that there is a much simpler solution. Something like array accessing style, maybe.
I tried to do something like that:
#define getval(s,n) s.a##n
But expectedly it doesn't work.
Is there a nicer solution?
Unless you have specific knowledge of the underlying structure of the struct, there is no way to implement such a method in C. There are all sorts of problems that will get in the way including
Members of different sizes
Packing issues
Alignment issues
Tricks like bitfields will be problematic
You're best off implementing a method by hand for your struct which has a deep understanding of the internal members of the structure.
If every field in your struct is an int, then you should basically be able to say
int getval(struct Element *ep, int n)
{
return *(((int*)ep) + n);
}
This casts the pointer to your struct to a pointer to an array if integers, then accesses the nth element of that array. Since everything in your struct seems to be an integer, this is perfectly valid. Note that this will fail horribly if you ever have a non-int member.
A more general solution would be to maintain an array of field offsets:
int offsets[3];
void initOffsets()
{
struct Element e;
offsets[0] = (int)&e.x - (int)&e;
offsets[1] = (int)&e.y - (int)&e;
offsets[2] = (int)&e.z - (int)&e;
}
int getval(struct Element *ep, int n)
{
return *((int*)((int)ep+offsets[n]));
}
This will work in the sense that you'll be able to call getval for any of the int fields of your struct, even if you have other non-int fields in your struct, since the offsets will all be correct. However, if you tried to call getval on one of the non-int fields it would return a completely wrong value.
Of course, you could write a different function for each data type, e.g.
double getDoubleVal(struct Element *ep, int n)
{
return *((double*)((int)ep+offsets[n]));
}
and then just call the proper function for whichever datatype you'd want. Incidentally, if you were using C++ you could say something like
template<typename T>
T getval(struct Element *ep, int n)
{
return *((T*)((int)ep+offsets[n]));
}
and then it would work for whatever datatype you'd want.
If your struct was anything except bitfields, you could just use array access, if I'm right in remembering that C guarantees that a series of members of a struct all of the same type, has the same layout as an array. If you know which bits in what order your compiler stores bitfields into integer types, then you could use shift/mask ops, but that's then implementation-dependent.
If you want to access bits by variable index, then it's probably best to replace your bitfields with an integer containing flag bits. Access by variable really isn't what bitfields are for: a1 ... an are basically independent members, not an array of bits.
You could do something like this:
struct Element {
unsigned int a1 : 1;
unsigned int a2 : 1;
...
unsigned int an : 1;
};
typedef unsigned int (*get_fn)(const struct Element*);
#define DEFINE_GETTER(ARG) \
unsigned int getter_##ARG (const struct Element *ep) { \
return ep-> a##ARG ; \
}
DEFINE_GETTER(1);
DEFINE_GETTER(2);
...
DEFINE_GETTER(N);
get_fn jump_table[n] = { getter_1, getter_2, ... getter_n};
int getval(struct Element *ep, int n) {
return jump_table[n-1](ep);
}
And some of the repetition could be avoided by the trick where you include the same header multiple times, each time having defined a macro differently. The header expands that macro once for each 1 ... N.
But I'm not convinced it's worth it.
It does deal with JaredPar's point that you're in trouble if your struct mixes different types - here all the members accessed via a particular jump table must of course be of the same type, but they can have any old rubbish in between them. That still leaves the rest of JaredPar's points, though, and this is a lot of code bloat for really no benefit compared with the switch.
No, there is no simple way to do this easier. Especially for bitfields, that are hard to access indirectly through pointers (you cannot take the address of a bitfield).
You can of course simplify that function to something like this:
int getval(const struct Element *ep, int n)
{
switch(n)
{
case 1: return ep->a1;
case 2: return ep->a2;
/* And so on ... */
}
return -1; /* Indicates illegal field index. */
}
And it seems obvious how the implementation can be further simplified by using a preprocessor macro that expands to the case-line, but that's just sugar.
If the structure really is as simple as described, you might use a union with an array (or a cast to an array) and some bit-access magic (as in How do you set, clear and toggle a single bit in C?).
As Jared says, the general case is hard.
I think your real solution is to not use bitfields in your struct, but instead define either a set type or a bit array.
I suggest code generation. If your structures don't contain huge amount of fields you can auto generate routines for each field or for a range of fields
and use them like:
val = getfield_aN( myobject, n );
or
val = getfield_foo( myobject );
If you have
Only bitfields, or all the bitfields first in your struct
less than 32 (or 64) bitfields
then this solution is for you.
#include <stdio.h>
#include <stdint.h>
struct Element {
unsigned int a1 : 1;
unsigned int a2 : 1;
unsigned int a3 : 1;
unsigned int a4 : 1;
};
#define ELEMENT_COUNT 4 /* the number of bit fields in the struct */
/* returns the bit at position N, or -1 on error (n out of bounds) */
int getval(struct Element* ep, int n)
{
if(n > ELEMENT_COUNT || n < 1)
return -1;
/* this union makes it possible to access bit fields at the beginning of
the struct Element as if they were a number.
*/
union {
struct Element el;
uint32_t bits;
} comb;
comb.el = *ep;
/* check if nth bit is set */
if(comb.bits & (1<<(n-1))) {
return 1;
} else {
return 0;
}
}
int main(int argc, char** argv)
{
int i;
struct Element el;
el.a1 = 0;
el.a2 = 1;
el.a3 = 1;
el.a4 = 0;
for(i = 1; i <= ELEMENT_COUNT; ++i) {
printf("el.a%d = %d\n", i, getval(&el, i));
}
printf("el.a%d = %d\n", 8, getval(&el, 8));
return 0;
}
Based on eli-courtwright solution but without using array of field offsets
......
if you have a structure containing pointer field like this, maybe you could write:
struct int_pointers
{
int *ptr1;
int *ptr2;
long *ptr3;
double *ptr4;
std::string * strDescrPtr;
};
Then you know that every pointer has a 4 bytes offset from a pointer to the structure, so you can write:
struct int_pointers ptrs;
int i1 = 154;
int i2 = -97;
long i3 = 100000;
double i4 = (double)i1/i2;
std::string strDescr = "sample-string";
ptrs.ptr1 = &i1;
ptrs.ptr2 = &i2;
ptrs.ptr3 = &i3;
ptrs.ptr4 = &i4;
ptrs.strDescrPtr = &strDescr;
then, for example, for a int value you can write:
int GetIntVal (struct int_pointers *ep, int intByteOffset)
{
int * intValuePtr = (int *)(*(int*)((int)ep + intByteOffset));
return *intValuePtr;
}
Calling it by:
int intResult = GetIntVal(&ptrs,0) //to retrieve the first int value in ptrs structure variable
int intResult = GetIntVal(&ptrs,4) //to retrieve the second int value in ptrs structure variable
and so on for the others structure fields values (writing other specific functions and using correct bytes offset value (multiple of 4)).
Although the OP specifies that we shouldn't care about the contents of the struct, since they are just bitfields would it be possible to use a char or int (or whatever data type has the size required) to create an n-bit "array" in this case?
void writebit(char *array, int n)
{
char mask = (1 << n);
*array = *array & mask;
}
with the char types replaced with a larger type if a longer "array" was needed. Not sure this is a definitive solution in other structs but it should work here, with a similar readbit funcition.
If you want to access your structure using both element index:
int getval(struct Element *ep, int n)
and by name:
ep->a1
then you are stuck with some hard to maintain switch like method that everyone has suggested.
If, however, all you want to do is access by index and never by name, then you can be a bit more creative.
First off, define a field type:
typedef struct _FieldType
{
int size_in_bits;
} FieldType;
and then create a structure definition:
FieldType structure_def [] = { {1}, {1}, {1}, {4}, {1}, {0} };
The above defines a structure with five elements of size 1, 1, 1, 4 and 1 bits. The final {0} marks the end of the definition.
Now create an element type:
typedef struct _Element
{
FieldType *fields;
} Element;
To create an instance of an Element:
Element *CreateElement (FieldType *field_defs)
{
/* calculate number of bits defined by field_defs */
int size = ?;
/* allocate memory */
Element *element = malloc (sizeof (Element) + (size + 7) / 8); /* replace 7 and 8 with bits per char */
element->fields = field_defs;
return element;
}
And then to access an element:
int GetValue (Element *element, int field)
{
/* get number of bits in fields 0..(field - 1) */
int bit_offset = ?;
/* get char offset */
int byte_offset = sizeof (Element) + bit_offset / 8;
/* get pointer to byte containing start of data */
char *ptr = ((char *) element) + byte_offset;
/* extract bits of interest */
int value = ?;
return value;
}
Setting values is similar to getting values, only the final part needs changing.
You can enhance the above by extending the FieldType structure to include information about the type of value stored: char, int, float, etc, and then write accessors for each type which checks the required type against the defined type.
Why not build getval() in to the struct?
struct Whang {
int a1;
int a2;
int getIth(int i) {
int rval;
switch (i) {
case 1: rval = a1; break;
case 2: rval = a2; break;
default : rval = -1; break;
}
return rval;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
Whang w;
w.a1 = 1;
w.a2 = 200;
int r = w.getIth(1);
r = w.getIth(2);
return 0;
}
getIth() would have knowledge of the internals of Whang, and could deal with whatever it contained.