tags:

views:

115

answers:

1

So, we have this homework assignment that builds off of last weeks. We are supposed to create separate arrays that hold pointers to all the people of a certain job type. Here is the code I have so far. I was wondering if any one can help me out. Thanks!

#include <stdio.h>
#include <stdlib.h>
#include "Person.h"
#include "data.h"
#define new

char * randomVal(char * arr[], int elements)
{
    int value = (int)(rand() % elements);
    char * name = arr[value];
    return name;
}

int main (int argc, const char * argv[]) 
{
    Person * Population[100];
    int i;
    for (i = 0; i < 100; i++)
    {
     Population[i] = new person(randomVal(Names, 10), randomVal(Vehicles, 5), randomVal(Jobs, 5), randomVal(Job_Pace, 3), randomVal(Education, 4), randomVal(Work_Ethic, 3), randomVal(Sleep_Habits, 3));
     Population[i]->print(Population[i]);
    }
    for (i=0; i<100; i++) {
     destroy(Population[i]);
    }
    //Person * p1 = new person(randomName(), "Camero", "Lawyer", "Fast", "Doctorate", "Poor", "Poor");
    //p1->print(p1);


    return 0;
}


/*
 *  Person.h
 *  Person2
 *
 *  Created by Tracie Marshall on 10/15/09.
 *  Copyright 2009 Me. All rights reserved.
 *
 */

typedef struct
{
    //data
    //dynamic sized vars
    char * name;
    char * vehicle;
    char * job;
    char * job_pace;
    char * education;
    char * work_ethic;
    char * sleep_habits;

    //static-sized vars
    double bank_account;
    int leadership;
    int IQ;
    int aggro;
    int outfit;
    int alertness;

    //methods
    void (*print)(void *);
} Person;

Person * person(char * n, char * v, char * j, char * jp, char * ed, char * w, char * s);
void printPerson(Person* p);
void destroy(Person * p);

/*
 *  Person.c
 *  Person2
 *
 *  Created by Tracie Marshall on 10/15/09.
 *  Copyright 2009 Me. All rights reserved.
 *
 */

#include <string.h>
#include <stdlib.h>
#include "Person.h"
#include <stdio.h>

char * newString(char * dest, char * source)
{
    dest = (char *)malloc((strlen(source) + 1) * sizeof(char));
    strcpy(dest, source);
    return dest;
}

void printPerson(Person* p)
{
    printf("\n%s:\n\tvehicle:\t%s\n\tjob:\t\t%s\n\tjob pace:\t%s\n\teducation:\t%s\n\twork ethic:\t%s\n\tsleep habit:\t%s", p->name, p->vehicle, p->job, p->job_pace, p->education, p->work_ethic, p->sleep_habits);//, p->age, p->job, p->spouse);
}

Person * person(char * n, char * v, char * j, char * jp, char * ed, char * w, char * s)
{
    //allocate self
    Person * p = (Person *) malloc(sizeof(Person));

    //allocate dynamic variables on stack
    p->name = newString(p->name, n);
    p->vehicle = newString(p->vehicle, v);
    p->job = newString(p->job, j);
    p->job_pace = newString(p->job_pace, jp);
    p->education = newString(p->education, ed);
    p->work_ethic = newString(p->work_ethic, w);
    p->sleep_habits = newString(p->sleep_habits, s);

    //initalize static-size variables
    p->bank_account; // = ba;
    p->IQ;
    p->aggro;
    p->outfit;
    p->alertness;

    //initialize function pointers
    p->print = &printPerson;

    return p;
}
void destroy(Person * p)
{
    free(p->name);
    free(p->vehicle);
    free(p->job);
    free(p->job_pace);
    free(p->education);
    free(p->work_ethic);
    free(p->sleep_habits);

    free(p);
}

/*
 *  data.h
 *  Person2
 *
 *  Created by Tracie Marshall on 10/15/09.
 *  Copyright 2009 Me. All rights reserved.
 *
 */

char * Names[10] = {"Lisa", "Pamela", "Amanda", "Gerard", "Dan", "Patrick", "Peter", "Michael", "Sally", "Tracie"};
char * Vehicles[5] = {"Feet", " Old Bike","New Bike", "Cheap Car", "Expensive Car"};
char * Jobs[5] = {"Unemployed", "Burger World", "Junior Programmer", "Senior Programmer", "Academia"};
char * Job_Pace[3] = {"Easy Going", "9-5 Grind", "Whirl Wind"};
char * Education[4] = {"Bum", "High School", "College", "Graduate School"};
char * Work_Ethic[3] = {"Drifter", "Hard Worker", "Workaholic"};
char * Sleep_Habits[3] = {"Good", "Medium", "Poor"};
+3  A: 

I'm not sure what your question is but I will try to update my answer when you update the question.

One thing to note is that you are using C++ (or C99) style comments (//comment here). If you are compiling with strict ANSI C90 support then this will fail. Also, don't cast the return of malloc (this stems from a very old problem that is not present in C90 and above compilers).

Also, this isn't ANSI C. You have this line:

Population[i] = new person(randomVal(Names, 10), ... /* snipped for brevity */

There is no "new" keyword in ANSI C. This isn't even the right syntax for C++ (Just eye-balling this at a glance looks like you could just drop the new and the person() function returns the right thing).

EDIT

Ok, this is response to the comment. There's a lot of ways you can do this. One simple way is to set a limit for the number of Persons that can have a particular job. Then you could create an array with the same size of your Jobs array and each index into this new array, say HasJob, could match the index into the Jobs array. So, HasJob[0] could store every Person that has the "Unemployed" job. You could keep a separate count for each HasJob entry, so then when you insert you know where to stick the new Person object, or you could just initialize all the values to NULL and then every time you insert, do a linear search.

So you could have:

/* 5 is the number of possible Jobs and 100 is the max persons per job */
Person *HasJob[5][100];

memset(HasJob, 0, 5*100*sizeof(Person *));

Now, you can insert each Person into the HasJob array by doing something like this

int i, j, k;
for(i=0; i < 5; i++)
{

  for(j=0; j < 100; j++)
  {

    if(strcmp(Population[j]->job, Jobs[i]) == 0)
    {
      k = 0;
      while(((p = HasJob[i][k]) != NULL) && (k < 100) k++;
      if(k != 100) /* if k == 100, somehow too many persons have this job */
      {
        HasJob[i][k] = Population[j];
      }

    }

  }

}

So, I haven't tried to compile that and there may be some issues but that is the general process for this way of doing it. Essentially, you go through each job, then for each job go go through each person; if that person is in that job, find an empty spot in HasJob and put that person there.

Again, lots of ways to do it. You could keep a count for each Job and then you wouldn't have to do the linear scan, but this method prevents you have from having to keep track and instantiate those variables. Another method is to use linked lists. This may give you an idea though. Of course, you should probably use #define's for each of those constant values (the maximum values, such as 5 and 100 could be MAX_JOBS, MAX_PERSONS, etc).

BobbyShaftoe
Since the code includes #define new, the objection to new is nominally moot - though the #define is not a good idea and I'm not sure how the remaining code works (I've not looked through all the code - I was just puzzling about why the #define was present).
Jonathan Leffler
@Jonathan Leffler, ah ... eh I'm keeping the objection. There is no new keyword in C. Yeah, there is a define there but it's pointless and useless. I'm not a compiler, I don't claim to catch every pointless #define that mimics keywords in other C *like* languages... I think it's a pretty reasonable objection. The big take away is: don't do that in "ANSI C."
BobbyShaftoe
@BobbyShaftoe - no disputing it is noxious C.
Jonathan Leffler