Better way to declare this huge struct? - c

I am creating an application which uses a vCard struct. Currently, this struct looks like this:
typedef struct {
char *version;
char **names;
char *formatted_name;
char *nickname;
char *organisation;
char *title;
struct { /* Emails */
char *global_type;
char *type;
char *address;
/* Meant to be a boolean which C doesn't have -_- */
unsigned preferred : 1;
} *emails;
struct { /* Phones */
char *type;
char *number;
unsigned preferred : 1;
} *phones;
struct { /* Addresses */
char *type;
char *street;
char *city;
char *postal_code;
char *country;
unsigned preferred : 1;
} *addresses;
time_t birthday;
struct { /* Custom Fields */
char *field_name;
union {
/* Single value */
int i;
float f;
double d;
time_t t;
struct {
char *global_type;
char *type;
char *address;
/* Meant to be a boolean which C doesn't have -_- */
unsigned preferred : 1;
} email;
struct {
char *type;
char *number;
unsigned preferred : 1;
} phone;
struct {
char *type;
char *street;
char *city;
char *postal_code;
char *country;
unsigned preferred : 1;
} address;
char *s;
/* Multiple values */
int *is;
float *fs;
double *ds;
time_t *ts;
struct {
char *global_type;
char *type;
char *address;
/* Meant to be a boolean which C doesn't have -_- */
unsigned preferred : 1;
} *emails;
struct {
char *type;
char *number;
unsigned preferred : 1;
} *phones;
struct {
char *type;
char *street;
char *city;
char *postal_code;
char *country;
unsigned preferred : 1;
} *addresses;
char **ss;
} field_value;
} *custom_fields;
} vCard;
This one is huge and takes much memory. I also use much pointers. Is there a better and cleaner way to declare this struct? Thanks.
Also, is it a good practise to use unions inside of structs and vice versa?

Yes! Split structs apart! (just like when there's a huge function.)
typedef struct {
char *global_type;
char *type;
char *address;
/* Meant to be a boolean which C doesn't have -_- */
unsigned preferred : 1;
} vCardEmail;
...
typedef struct { /* Custom Fields */
char *field_name;
union {
/* Single value */
int i;
float f;
double d;
time_t t;
vCardEmail email;
vCardPhone phone;
vCardAddress address;
char *s;
/* Multiple values */
int *is;
float *fs;
double *ds;
time_t *ts;
vCardEmail *emails;
vCardPhone *phones;
vCardAddress *addresses;
char **ss;
} field_value;
} vCardCustomField;
typedef struct {
char *version;
char **names;
char *formatted_name;
char *nickname;
char *organisation;
char *title;
vCardEmail *emails;
vCardPhone *phones;
vCardAddress *addresses;
time_t birthday;
vCardCustomField *custom_fields;
} vCard;

Related

What is the best way to set the bit field values using loops?

This is simple code; I am using this code snippet in my project and its working fine.
My question if it is the best way or otherwise What is the best way to set the bit fields using loops in C?
#define NUM_OF_MAX_SENSOR 10
typedef float SENSOR_VAL ;
typedef struct
{
unsigned char bit0:1;
unsigned char bit1:1;
unsigned char bit2:1;
unsigned char bit3:1;
unsigned char bit4:1;
unsigned char bit5:1;
unsigned char bit6:1;
unsigned char bit7:1;
}BYTE_FIELD;
typedef struct
{
BYTE_FIELD funP1;
BYTE_FIELD funP2;
}LOG_DATA;
LOG_DATA xlog;
typedef struct
{
unsigned char ok:1;
unsigned char open:1;
unsigned char shrt:1;
unsigned char unused:5;
}SENSOR_FLAGS;
typedef struct
{
SENSOR_FLAGS flag;
SENSOR_VAL val;
}SENSOR_DATA;
typedef union
{
SENSOR_DATA sensor[NUM_OF_MAX_SENSOR];
unsigned char buff[sizeof(SENSOR_DATA) * NUM_OF_MAX_SENSOR];
}SENSOR;
SENSOR sensor;
These are the structures I used and these are the max details I can provide.
void UpdateLogData()
{
int i = 0;
unsigned char *funPAddr =(unsigned char *) &xlog.funP1;
for(i=0;i<8;i++)
*(funPAddr) |= sensor.sensor[i].flag.ok << i;
printf("0x%x",*(funPAddr));
}
//main
int main()
{
sensor.sensor[0].flag.ok = 1;
sensor.sensor[4].flag.ok = 1;
sensor.sensor[5].flag.ok = 1;
sensor.sensor[6].flag.ok = 1;
sensor.sensor[7].flag.ok = 1;
UpdateLogData();
}

Pass String array and indexes using Struct to a thread in C

I am trying to pass a string array and indexes from where to start end searching in the array, I am unable to solve it from the last two days. I am sending to the pthread_create a struct data thread_data, here i am able to send the int and long data, but not the string array, can someone help me, how to pass these.
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
char * str;
};
struct data thread_data[NUM_THREADS];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
char * str[3];
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
.....
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
...
char work[]={"First Line","Second line","Third line"};
...
while(fgets(arr[index],120, fp)!=NULL){
index=index+1;
thread_data[index].tid=index;
thread_data[index].str=work;
...
rc=pthread_create(&threads[index],NULL,searchString,(void *)&thread_data[index]);
...
}
pthread_exit(NULL);
}
To hold the multiple strings you need 2D array.
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
You need to use pointer to pointer in struct data to hold the above array.
struct data{
.....
const char **str;
size_t lenOfStr;
};
And pass the length of array explicitly to thread function from main function.
Your sample code may look like below.
#include<stdio.h>
#include<stdlib.h>
#include<pthread.h>
struct data{
int tid;
unsigned long start;
unsigned long end;
char * word;
const char **str;
size_t lenOfStr;
};
struct data thread_data[3];
void *searchString(void *passeddata)
{
struct data *t_data;
int tid1;
const char **str = NULL;
t_data=(struct data *) passeddata;
tid1=t_data->tid;
str=t_data->str;
int i = 0;
for (i = 0;i<t_data->lenOfStr;i++)
printf("%s\n", str[i]);
pthread_exit(NULL);
}
int main(int argc, char *argv[])
{
const char *work[]={"First Line","Second line","Third line", "Fourth Line"};
int index = 0;
pthread_t threadid=0;
thread_data[index].tid=index;
thread_data[index].str=work;
thread_data[index].lenOfStr = sizeof(work)/sizeof(*work); // Calculate the size of work here
int rc=pthread_create(&threadid,NULL,searchString,&thread_data[index]);
pthread_exit(NULL);
}

Expression must be pointer to complete object type?

I am trying to make changes to an array of structures. My code is as follows:
typedef struct {
char firstName[30];
char lastName[30];
char street[35];
char city[20];
char state[3];
int zip;
char phone[15];
int accountId;
} Customer;
struct Customer customer_list[];
//void copy_first_name(char data[], int i) {
// strcpy(customer_list[i].)
//}
int main(void) {
int _zip, _accountId;
char _firstName[30], _lastName[30], _street[35], _city[20], _state[3], _phone[15];
for (int i = 0; i < 10; i++) {
printf("Enter data for customer %d: \n", i);
printf("Enter First Last Phone: ");
scanf("%s%s%s", &_firstName, &_lastName, &_phone);
printf("\nEnter Address (Street City State ZIP): ");
scanf("%s%s%s%d", &_street, &_city, &_state, &_zip);
strcpy(customer_list[i].firstName, _firstName);
}
return 0;
}
I get the error message in the title, referring to customer_list. Can anyone help me out?
Change
struct Customer customer_list[];
to
Customer customer_list[10];
or (not recommended, but an example of the syntax)
struct Customer {
char firstName[30];
char lastName[30];
char street[35];
char city[20];
char state[3];
int zip;
char phone[15];
int accountId;
} customer_list[];
In your example, Customer is a typedef, equal to struct { ... }. It is not a named struct.
Some people like to do this, but I don't like it:
typedef struct Customer {
char firstName[30];
char lastName[30];
char street[35];
char city[20];
char state[3];
int zip;
char phone[15];
int accountId;
} Customer;
Customer customer_list[10];
or
struct Customer customer_list[10];
It would be better if they did:
typedef struct Customer_s {
char firstName[30];
char lastName[30];
char street[35];
char city[20];
char state[3];
int zip;
char phone[15];
int accountId;
} Customer;
Now it is clear that there is a difference between Customer and Customer_s.
Customer customer_list[10];
or
struct Customer_s customer_list[10];
You have [typedef][1] in struct so while declaring no need of struct keyword
do simply
Customer customer_list[10];
is enough.
or remove the typedef and declare struct like this ..
struct Customer {
char firstName[30];
char lastName[30];
char street[35];
char city[20];
char state[3];
int zip;
char phone[15];
int accountId;
} ;
struct Customer customer_list[10];

Accessing structure members in C

Actually few hours back, I had posted a question but there was some error in my question (My bad!!). I want to access the members of a structure (profile_t) which is placed inside a structure (profile_datagram_t) and profile_t is a array of structs....
struct profile_t
{
unsigned char length;
unsigned char type;
unsigned char *data;
};
typedef struct profile_datagram_t
{
unsigned char src[4];
unsigned char dst[4];
unsigned char ver;
unsigned char n;
struct profile_t profiles[MAXPROFILES];
} header;
This sets the length of the first profile in the headers to 10:
header h;
h.profiles[0].length = 10;

Visual Studio 2008 Intellisense with struct keyword

I am using visual studio 2008 express edition.
A normal win32 console C project with the code below:
int main(void)
{
struct _addr_info
{
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_info;
addr_info.zip = 12345;
return 0;
}
Generally for structures intellisense will list the members. Here it doesnt however it compiles fine and at debugging i checked the data also gets entered properly. Am i doing something wrong.
even this code has same prob.
int main(void)
{
struct
{
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_info;
addr_info.zip = 12345;
return 0;
}
This code below also doesn't work.
int main(void)
{
struct _addr_info
{
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} ;
struct _addr_info addr_info;
addr_info.zip = 12345;
return 0;
}
The code below works fine and list the members of the structure.
struct _addr_info
{
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} addr_info;
int main(void)
{
addr_info.zip = 12345;
return 0;
}
This one too.
struct _addr_info
{
char name[30];
char street[40];
char city[20];
char state[3];
unsigned long int zip;
} ;
int main(void)
{
struct _addr_info addr_info;
addr_info.zip = 12345;
return 0;
}
I posted on MSDN forum and got the answer pointed by the link.
http://social.msdn.microsoft.com/Forums/en-US/Vsexpressvc/thread/8a22dc4a-3632-4cb9-92a3-63a18b55e7b6
Hope this helps.
If you're used to Visual C#'s intellisense then you'll be extremely disappointed in Visual C++'s as it's very buggy. You can try deleting the ncb files but you're better off using something like Visual Assist which is an intellisense replacement.
Answer copied from [ Why does Visual Studio not know the correct definition of this struct? ]
There's something about your situation described by Microsoft: http://support.microsoft.com/kb/822551
WORKAROUND: Microsoft strongly recommends that you use unique type
definitions.

Resources