Peter said:
Peter "Shaggy" Haywood said:
Groovy hepcat Franz was jivin' on 17 Feb 2004 03:53:33 -0800 in
comp.lang.c.
Problems dereferensing my C structures (custom types)'s a cool scene!
Dig it!
Greetings,
I have created the following types:
typedef struct _tbl_certificate{
int cert_id;
char *cert_name;
}tbl_certificate;
typedef struct _cameraObj{
tbl_camera camera;
tbl_certificate *certificate;
}cameraObj;
I am having trouble accessing the certificate array in the cameraObj struct.
eg. cameraObj *camera;
camera->certificate[0].cert_id = 7;
This doesn't want to work. Any suggestions or ideas would be greatly
appreciated!
The other answers were correct and you should pay heed to them,
As should you.
but they missed one important thing. The -> operator dereferences the
pointer, but so does the [0] operator. You're dereferencing twice. You
need to do so only once. Remove the -> and use a dot in its place if
the pointer points at an array of tbl_certificate, or remove the [0]
otherwise. Ie.:
camera.certificate[0].cert_id = 7;
or
camera->certificate.cert_id = 7;
Both camera and certificate are pointer types in the quoted context above,
so the . operator is not an applicable to either.
The allocations are not shown. However, with the syntax
certificate[0], we can see that certificate is an array.
If it is an array of the struct pointers, then the -> operator is needed.
If it is an array of the struct objects, then the . operator is needed.
For an example of the later, see function AddCertificate in the following
example.
/* code untested */
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#define END 0
typedef struct _tbl_certificate{
int cert_id;
char *cert_name;
}tbl_certificate;
typedef struct _cameraObj{
char *camera_name;
tbl_certificate *certificate;
size_t cert_nr;
}cameraObj;
/* Prototypes */
char *CameraName(cameraObj *p, const char *name);
tbl_certificate *AddCertificate(cameraObj *p, int id,
const char *name);
void PrintInfo(cameraObj *p);
void FreeCertificates(cameraObj *p);
void FreeCamera(cameraObj *p);
int AddCameraInfo(cameraObj *p,const char *camera_name,
int cert_nr, ...);
int main(void)
{
cameraObj mycamera = {NULL};
CameraName(&mycamera, "Minolta");
AddCertificate(&mycamera, 326, "USDA");
AddCertificate(&mycamera, 4566,"Institute of Technology");
PrintInfo(&mycamera);
puts("Let's buy a new camera\n");
FreeCamera(&mycamera);
AddCameraInfo(&mycamera, "Kodak", /* Camera Name */
356,"MIT", /* Certificate 1 values */
221,"Computer Shopper", /*certificate 2 values */
END);
PrintInfo(&mycamera);
puts("Add another certificate\n");
AddCertificate(&mycamera,444,"Computer Magazine");
PrintInfo(&mycamera);
puts("The certificates have expired\n");
FreeCertificates(&mycamera);
PrintInfo(&mycamera);
FreeCamera(&mycamera);
return 0;
}
char *CameraName(cameraObj *p, const char *name)
{
char *tmp;
if((tmp = realloc(p->camera_name,strlen(name)+1)) != NULL)
{
strcpy(tmp,name);
p->camera_name = tmp;
}
return tmp;
}
tbl_certificate *AddCertificate(cameraObj *p, int id, const char *name)
{
tbl_certificate *tmp;
if((tmp = realloc(p->certificate,
(p->cert_nr+1)*sizeof *tmp)) == NULL) return NULL;
if((tmp[p->cert_nr].cert_name = malloc(strlen(name)+1)) == NULL)
return NULL;
strcpy(tmp[p->cert_nr].cert_name,name);
p->certificate = tmp;
strcpy(p->certificate[p->cert_nr].cert_name,name);
p->certificate[p->cert_nr++].cert_id = id;
return tmp;
}
void PrintInfo(cameraObj *p)
{
size_t i;
printf("Camera name: ");
if(p->camera_name)
puts(p->camera_name);
else puts("No Camera Name" );
if(!p->cert_nr) puts("No Certificates");
else
for(i = 0; i < p->cert_nr;i++)
printf("Certificate %u: ID: %d Name: %s\n",
i+1,p->certificate
.cert_id,
p->certificate.cert_name);
putchar('\n');
return;
}
void FreeCertificates(cameraObj *p)
{
size_t i;
for(i = 0; i < p->cert_nr; i++)
free(p->certificate.cert_name);
free(p->certificate);
p->certificate = NULL;
p->cert_nr = 0;
return;
}
void FreeCamera(cameraObj *p)
{
FreeCertificates(p);
free(p->camera_name);
p->camera_name = NULL;
return;
}
int AddCameraInfo(cameraObj *p,const char *camera_name,
int cert_nr, ...)
{
size_t cnt;
int id;
const char *cert_name;
va_list marker;
if(!CameraName(p,camera_name)) return 0;
va_start(marker,cert_nr);
for(cnt = 0, id = cert_nr; id != END; cnt++,
id = va_arg(marker,int))
{
cert_name = va_arg(marker,const char *);
if(!AddCertificate(p,id,cert_name))
{
FreeCamera(p);
return 0;
}
}
p->cert_nr = cnt;
va_end(marker);
return 1;
}