C access struct in struct - c

A project in C is being forced upon me. I do not have much C knowledge, but I'm assuming the answer is simple.
struct s1 {
char *text;
int num;
};
struct s2 {
struct s1 vals[5];
int numbers;
};
Assume s2 is already populated. How do access num from s1? I was assuming I would do something like
struct s2 temp;
//temp is populated somehow, doesn't matter in the case
printf("%d\n", temp.vals[0]->num);
but that doesnt work. Any suggestions?

Use temp.vals[0].num. The -> operator can only be used if you are using a pointer to a struct. You are using a struct directly.

Related

How to convert pointer array to char array?

I have this:
typedef struct nodebase{
char name[254];
char sex;
int clientnum;
int cellphone;
struct nodebase *next;
struct nodebase *encoding;
} clientdata;
I have added clientdata *curr[]; in seperate function. The reason why I made *curr into *curr[] instead is that this client data will be stored in a .txt file. So I came up with singly linked-list to read all the data and when the program fscanf every 5th variable, I will add 1 to clientcounter.
So, the *curr[] will be *curr[clientcounter].
Now, I need to convert this pointer array into char array named temp[clientcounter] because char array is needed to evaluate something else later in the code.
I came up with this code below:(Using Tiny C on Windows)
void loaded_data_transfer(clientdata *curr,clientdata temp[],int clientcounter)
{
clientdata temp[] = {0};
temp[clientcounter].name = curr[clientcounter]->name;
temp[clientcounter].sex = curr[clientcounter]->sex;
temp[clientcounter].clientnum = curr[clientcounter]->clientnum;
temp[clientcounter].cellphone = curr[clientcounter]->cellphone;
}
The problem is, Tiny C is giving me an error: lvalue expected at temp[clientcounter.name = ... part. Can anyone tell me what did I do wrong?
And if anyone knows a better way to keep track of the curr of clientdata by using counter and by using singly linked-list, please let me know.
You cannot assign an array to another. You should use strcpy or strncpy
strcpy(temp[clientcounter].name, curr[clientcounter]->name);
Maybe you meant to copy the entire struct:
void loaded_data_transfer(clientdata * curr, clientdata temp[], int clientcounter)
{
temp[clientcounter] = *curr; // Copy entire struct
}
It should work, because your struct doesn't any pointer members.
I am assuming you use it like this
clientdata * curr[CURR_SIZE];
clientdata temp[TEMP_SIZE];
/* init curr elements here */
loaded_data_transfer(*curr[clientcounter], temp, clientcounter);
Also, your declaration should be:
void loaded_data_transfer(clientdata *curr[],...

Pointer to struct

I am working on assignment. I started with the struct:
struct figures_struct
{
char figure_name[130];
double figure_coordinates[1000000];
};
When I read name of the figure from the file, I stored it into the struct as follows:
strcpy(figures[i].figure_name,f_name);
Now I have to modify my code and need to use dynamic memory. I did:
struct figures_struct
{
char figure_name[130];
double figure_coordinates[100000];
};
struct figures_struct *figures = malloc(size * sizeof(struct figures_struct));
Now, how do I store figure name into my struct? figures[i].figure_name does not seem to be working.
strcpy(figures[i].figure_name, f_name);
That will still work with pointers(as pointers and arrays are almost interchangeable in C)
It will work as soon as "i" is less than "size".

Returning an identical struct but with a different name

struct s1 { int a; int b; };
struct s2 { int a; int b; };
struct s2 test(void) {
struct s1 s = { 1, 2 };
return s; // incompatible types
}
In the above code, can I return s without creating a new struct s2 variable and populating it with s's values? It is guaranteed that struct s1 will always be identical to struct s2.
You can't return the struct directly, but you can avoid
creating a separate variable in your source code by using a compound literal,
which is a feature of C99.
struct s2 test(void) {
struct s1 s = { 1, 2 };
return (struct s2){s.a, s.b};
}
Besides nos answer .. Note: [For Demo Only, its not an answer]
This is a real bad way to do it(Not suggested), but it can decieve compiler:-
struct s1 { int a; int b; };
struct s2 { int a; int b; };
struct s2 test(void)
{
struct s1 s = { 1, 2 };
return *((struct s2*)(void*)&s);
}
Its behaviour solely depends on compiler.If s1 and s2 are arranged same way then this works.
I guess, as your coment suggest, that you are getting a compiler error.
I suggest you cast the return statement:
return (struct s2) s;
it should work, instinctively. And if it doesn't maybe you can tweak the compiler to skip the checking by making the error a warning.
And just for curiosity, why do you need this?
You can return by casting, but shouldn't.
Casting will work here since you are confident that the bytes will be exactly the same so that at the memory level an s2 can be interpreted as an s1 faithfully.
However if someone ever adds a new field in s2 this will break horribly, etc. From a programming or software engineering perspective, you should convert, and if you really do expect s1 and s2 to stay compatible, you should write a copy ctor or translator or whatever to get from one to the other.

Can't access my array of structs

I've declared an array of structs as so:
typedef struct{
int source;
int dest;
int type;
int port;
char data;
}test;
test packet[50];
and I'm trying to access the array and print it to the screen as such:
for (p = 0; p < i; p++)
{
printf("%i", packet[p]);
}
But I'm not getting what I expect. I'm very new at C so I'm sorry for any problems with this post. Just ask for more information and I'll give it. Have I got the logic completely wrong with this?
In my head I've created an 50 instances of the struct in an array with each element of the array containing the 5 variables in the struct.
It's been ages since I've done C but I don't think it works that way. You might want to print the struct's member variables one by one.
for (p = 0; p < i; p++)
{
printf("%i\n", packet[p].source);
printf("%i\n", packet[p].dest);
printf("%i\n", packet[p].type);
printf("%i\n", packet[p].port);
}
Or better yet, make a method, call it something like printTest() and have it do the above.
In your example above, you're trying to print the whole object, which wouldn't work.
Given
typedef struct{
int source;
int dest;
int type;
int port;
char data;
}test;
test packet[50];
your must explicitly reference each and every field you want to access. In the case of your example, you wish to print each field of the structure, so you will need to refer specifically to each field, like this: printf("%i\n", packet[0].source);
Your specific example was in a for loop with p as the array index, so the actual code would be printf("%i\n", packet[p].source);
Finally, you can easily discuss some C constructs in C++, but not C++ constructs, like classes, in C.

C: copying struct/array elements

I have a file in a known format and I want to convert it to a new format, eg.:
struct foo {
char bar[256];
};
struct old_format {
char name[128];
struct foo data[16];
};
struct new_format {
int nr;
char name[128];
struct foo data[16];
};
static struct old_format old[10];
static struct new_format new[10];
Problem: after filling 'old' with the data I don't know how to copy its content to 'new'. If I do
new[0].name = old[0].name;
new[0].data = old[0].data;
I get a compile error about assigning char * to char[128] (struct foo * to struct foo[16], respectively).
I tried a solution I found via Google for the string part:
strcpy (new[0].name, old[0].name);
new[0].data = old[0].data;
but I have no idea how to handle the struct. Seems I lack basic understanding of how to handle arrays but I don't want to learn C - I just need to complete this task.
If you don't want to learn C, you should be able to read the old file format in any language with a half-decent IO library.
To complete what you're trying to do in C, you could use memcpy.
So instead of:
new[0].data = old[0].data;
Use
memcpy(new[0].data, old[0].data, sizeof(foo) * 16);
You can also wrap the C arrays in a struct. Then copying elements will copy the array automatically.
typedef struct {
char name[100];
} name_array_t;
struct {
name_array_t name_struct;
...
} x;
struct {
name_array_t name_struct;
... other members ...
} y;
x.name_struct = y.name_struct;
(too obvious solution may be)
As we are dealing with the array, we can not do this kind of operation
new.name = old.name;
so i suppose you have to write a function
void Function (char *name , struct new_format *new );
where you need to assign charecter one by one.
Obviously you will Call like this : Function (old.name , &new)

Resources