Computer Wizard wrote:
Hello,
I am really scrwed up with the following stuff:
struct employee
{
char* employee_name;
};
You'll need to allocate memory for each employee name. That's OK.
struct department
{
char* department_name ;
struct employee* emp; /* Collection of all employees in a department */
};
Your '//' comment wrapped to the next line. When posting code to Usenet
groups like comp.lang.c you're better off using traditional /* */
comments that will not prevent compilation if wrapped.
You can allocate a block of memory for emp, like an array of employees.
You then face the problem of how to know how many employees are in the
array. If you don't want to add another entry to the department struct,
you can use the employee_name pointer to determine the end of the array.
If the employee_name is null, then that is the end of the array.
In main(), I wrote
struct department* company;
Ok, similarly here you can allocate a block of memory for company, like
an array of departments. Similarly you can use a null department_name to
determine the end of the company array.
I want to first enter the name of department and
then names of employees in that department. I tried with pointers but I
must hv messed up somewhere n getting segmentation faults.
It's pretty easy to mess up in C. Make sure you initialised each pointer
properly, and that it is pointing to valid memory. Make sure there is
enough memory allocated for each item you try to store into it. If you
need to extend an allocated array to make room for more elements, you
can use realloc().
Tried using
array representation e.g. company[i].emp[j].employee_name . This also
failed. I used new operator but it didn't help. Please tell me how to
deal such thing in pointers.
company[i].emp[j].employee_name should work, so long as you allocated
memory for company, emp and employee_name.
company = malloc(sizeof *company);
if(!company) exit(EXIT_FAILU RE);
company[0].emp = malloc(sizeof *company[0].emp);
if(!company[0].emp) exit(EXIT_FAILU RE);
company[0].emp[0].employee_name
= malloc(sizeof *company[0].emp[0].employee_name) ;
if(!company[0].emp[0].employee_name) exit(EXIT_FAILU RE);
Others have suggested using a linked list. That is one option, but if
you want to use the structs you have given above without any
modification, then a realloc solution is a reasonable way to go.
Here's some example code that I think does what you're trying to do.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct employee
{
char* employee_name;
};
struct department
{
char* department_name ;
struct employee* emp; /* Collection of all employees
in a department */
};
void err_mem(void)
{
fprintf(stderr, "Error allocating memory\n");
exit(EXIT_FAILU RE);
}
/* mallocs a copy of the given string and removes
a newline character if it is present */
char *get_str(const char *buf)
{
char *p = malloc(strlen(b uf) + 1), *q;
if(!p) err_mem();
strcpy(p, buf);
q = strchr(p, '\n');
if(q) *q = 0;
return p;
}
void add_department( struct department *company)
{
char buf[128];
size_t n = 0, alloc = 8; /* initial allocation */
printf("Enter department name: ");
fflush(stdout);
fgets(buf, sizeof buf, stdin);
company->department_nam e = get_str(buf);
company->emp = malloc(alloc * sizeof *company->emp);
if(!company->emp) err_mem();
do
{
printf("Enter employee name or just hit Enter when done: ");
fflush(stdout);
fgets(buf, sizeof buf, stdin);
if(buf[0] != '\n')
{
company->emp[n].employee_name = get_str(buf);
n++;
if(n == alloc)
{
void *p;
alloc *= 2;
p = realloc(company->emp, alloc * sizeof *company->emp);
if(!p) err_mem();
company->emp = p;
}
}
} while(buf[0] != '\n');
/* NULL employee name indicates the
end of the array of employees */
company->emp[n].employee_name = NULL;
}
struct department *new_company(vo id)
{
size_t n = 0, alloc = 8;
char buf[128];
struct department *company = malloc(alloc * sizeof *company);
if(!company) err_mem();
add_department( company + n);
n++;
do
{
printf("Do you want to add another department? (yes/no) ");
fflush(stdout);
fgets(buf, sizeof buf, stdin);
if(!strcmp(buf, "yes\n"))
{
add_department( company + n);
n++;
if(n == alloc)
{
void *p;
alloc *= 2;
p = realloc(company , alloc * sizeof *company);
if(!p) err_mem();
company = p;
}
}
} while(strcmp(bu f, "no\n"));
/* NULL department name indicates the
end of the array of departments */
company[n].department_nam e = NULL;
return company;
}
void print_departmen t(const struct department *department)
{
size_t i;
printf("Departm ent %s:\n", department->department_nam e);
for(i = 0; department->emp[i].employee_name != NULL; i++)
{
printf("Employe e %d: %s\n", i + 1,
department->emp[i].employee_name) ;
}
}
void print_company(c onst struct department *company)
{
size_t i;
for(i = 0; company[i].department_nam e != NULL; i++)
{
print_departmen t(company + i);
}
}
int main(void)
{
struct department *company = new_company();
print_company(c ompany);
return 0;
}
--
Simon.