#1
  1. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    20
    Rep Power
    0

    Dynamic Records CS Assignments


    So I have a CS assignment that I've been working on for some time now. I must create dynamic "records" using typedef and pointers. I understand this may make things a little more difficult but this is how my professor wants things done. I am stuck at allocating memory for my structure and anytime I try to add anything into a field the actual field points to NULL. Please let me know what I am doing wrong here and also if you can explain somewhat what is going on in memory with the solution I would greatly appreciate it.

    >Link_To_Picture_Of_Diagram_For_Assignment<

    MYCODE:

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    typedef struct{
    	char *name;
    	char *title;
    	char *ssnum;
    	double salary;
    	int withhold;
    } *employeeT;
    
    typedef struct{
    	employeeT **employ; //ptr to a ptr to employeeT struct
    	int numberOfEmp;
    } *payrollT;
    
    int main(){
    	printf("How many employees: ");
    	fflush(stdout);
    	int userNum = 0, index = 0;
    	scanf("%d", &userNum);
    	payrollT pRoll;
    	/*
    	*	pRoll is a pointer to payRoll struct
    	*	it dereferences numberOfEmp 
    	*
    	*/
    	pRoll = (payrollT) malloc(sizeof *((payrollT) NULL));
    	pRoll->numberOfEmp = userNum;
    	//array of pointers
    	pRoll->employ = (employeeT **) malloc(userNum * sizeof(employeeT *));
    	for(index = 0; index < userNum; index++){
    		pRoll->employ[index] = (employeeT *) malloc(sizeof(employeeT));
    	}
    //	pRoll->employ = (employeeT *) malloc(userNum * sizeof *((employeeT) NULL));
    /*
    	index = 0;
    	while(index < userNum){	
    		//Have to malloc each record i think????
    //		pRoll->employ[index] = (employeeT) malloc(sizeof *(employeeT) NULL);
    		char temp[256];
    		printf("Employee #1:\n");
    		printf("Name: ");
    		fflush(stdout);
    		scanf("%s", temp);
    		strcpy(pRoll->employ[index]->name, temp);
    		
    
    		//This is temp
    		index = userNum;
    	}
    */
    //	printf("\nString is: %s\n", pRoll->employ[0]->name);
    	return 0;
    }
    I assigned userNum to index at the end of the while loop to exit the loop and test if the name field stored the user entered name. Thanks in advance
  2. #2
  3. Contributing User
    Devshed Demi-God (4500 - 4999 posts)

    Join Date
    Aug 2011
    Posts
    4,904
    Rep Power
    481
    I think you were allocating space for pointers rather than structures. Following version has comments where I changed your code. At least, some of the places. Example use:
    $ ./c
    How many employees: 3
    Employee #1:
    Name: dwl
    Employee #2:
    Name: expect me!
    Employee #3:
    Name: abc
    expect me!

    $

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    
    typedef struct {
      char*name,*title,*ssnum;
      double salary;
      int withhold;
    } employeeT;			/* changed, empoyeeT was a pointer */
    
    typedef struct {
      int numberOfEmp;
      employeeT**employee;
    } payrollT;			/* changed, was a pointer */
    
    void fail(char*message) {	/* inserted */
      fprintf(stderr,"\n%s, quitting.\n",message);
      exit(1);
    }
    
    void*mycalloc(size_t n, size_t a) { /* always test allocation success */
      void*p = calloc(n,a);
      if (NULL == p)
        fail("out of memory");
      return p;
    }
      
    char*mystrdup(char*s) {
      char*p = strdup(s);
      if (NULL == p)
        fail("out of memory");
      return p;
    }
    
    int main() {
      int userNum = 0, index = 0;
      payrollT*pRoll;
      printf("How many employees: ");
      if (1 != scanf("%d", &userNum))
        fail("bad input");
      while('\n'!=getchar())
        ;
      pRoll = mycalloc(1,sizeof(payrollT)); /* simplified */
      pRoll->numberOfEmp = userNum;
      pRoll->employee = mycalloc(userNum,sizeof(employeeT *));
      *pRoll->employee = mycalloc(userNum,sizeof(employeeT)); /* more efficient to allocate them all at once, perhaps */
      for (index = 1; index < userNum; index++)
        pRoll->employee[index] = pRoll->employee[index-1]+sizeof(employeeT);
    
      /* Here after you should no longer use userNum.  The rest could go in separate functions */
      for (index = 0; index < pRoll->numberOfEmp; ++index) {
        char temp[256];
        printf("Employee #%d:\n",index+1);
        fputs("Name: ",stdout);
        if (temp != fgets(temp,sizeof(temp),stdin))
          fail("maybe you closed the file?");
        pRoll->employee[index]->name = mystrdup(temp); /* allocate memory for name */
      }
    
      puts(pRoll->employee[1]->name); /* demonstration */
    
    
      return 0;
    }
    [code]Code tags[/code] are essential for python code and Makefiles!
  4. #3
  5. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    20
    Rep Power
    0
    Thank you very much b49P23TIvg,

    The way you implemented the structs is the way I know how to. Unfortunately my professor requires us to implement the structs as pointers ex)

    Code:
    typedef struct{
       int a;
       int b;
    } *example;
    He says never to refer to a record type without using a pointer so there is no reason to name the record type at all. Instead of using this:

    Code:
    typedef struct{
       int a;
       int b;
    } example;
    
    example *ex;
    He wants us to implement it like the code on the top. So when declaring example type it is already a pointer.

    Code:
    example ex; <- ex is a ptr
  6. #4
  7. No Profile Picture
    Registered User
    Devshed Newbie (0 - 499 posts)

    Join Date
    Jul 2012
    Posts
    20
    Rep Power
    0
    Fixed it and completed it. Here is the final result. Thanks

    Code:
    #include<stdio.h>
    #include<stdlib.h>
    #include<string.h>
    #define MAX_NAME_SZ 256
    
    typedef struct{
    	char *name;
    	char *title;
    	char *ssnum;
    	double salary;
    	int withhold;
    } *employeeT;
    
    typedef struct{
    	employeeT employ;
    	int numberOfEmp;
    } *payrollT;
    
    payrollT getPayRoll();
    void weeklyPay(payrollT pRoll);
    double calTax(double gross, int deduction);
    double calNet(double gross, int deduction);
    char *retNew(char *str1, char *str2, int space);
    
    int main(){
    	payrollT test = getPayRoll();
    	weeklyPay(test);
    	return 0;
    }
    
    payrollT getPayRoll(){
    	printf("How many employees: ");
    	fflush(stdout);
    	int userNum = 0, index = 0;
    	scanf("%d", &userNum);
    	payrollT pRoll;
    	pRoll = (payrollT) malloc(sizeof *((payrollT) NULL)); //creates single malloced space for 2 var
    	pRoll->numberOfEmp = userNum;
    	pRoll->employ = (employeeT) malloc(userNum * sizeof*((employeeT) NULL));
    	index = 0;
    	while(index < userNum){
    		char temp[MAX_NAME_SZ];
    		char temp2[MAX_NAME_SZ];
    		printf("Employee #%d:\n", (index+1));
    		printf("Name: ");
    		fflush(stdout);
    		scanf("%s %s", temp, temp2);
    		char *here = retNew(temp, temp2, 1);
    		pRoll->employ[index].name = strdup(here);
    		printf("Title: ");
    		fflush(stdout);
    		scanf("%s", temp);
    		pRoll->employ[index].title = strdup(temp);
    		printf("Social Security Number: ");
    		fflush(stdout);
    		scanf("%s", temp);
    		pRoll->employ[index].ssnum = strdup(temp);
    		printf("Enter Salary: ");
    		fflush(stdout);
    		scanf("%lf", &pRoll->employ[index].salary);
    		printf("Withholding Exemptions: ");
    		scanf("%d", &pRoll->employ[index].withhold);
    		index++;
    	}
    	return pRoll;
    }
    
    
    double calNet(double gross, int deduction){
    	double x = gross - (deduction * 1);
    	double cal = x * .25;
    	return (gross - cal);
    }
    
    double calTax(double gross, int deduction){
    	double x = gross - (deduction * 1);
    	double cal = x * .25;
    	return cal;
    }
    
    void weeklyPay(payrollT pRoll){
    	int track = pRoll->numberOfEmp, index;
    	printf("%s\t\t\t\t\t%s\t\t%s\t\t%s\n","Name","Gross","Tax","Net");
    	printf("-----------------------------------------------------------------------------\n");
    	for(index = 0; index < track; index++){
    		if(strlen(pRoll->employ[index].name) > 7){
    			printf("%s\t\t\t\t%.2lf\t-\t%.2lf\t\t%.2lf\n", (pRoll->employ[index].name), (pRoll->employ[index].salary), (calTax(pRoll->employ[index].salary, pRoll->employ[index].withhold)), (calNet(pRoll->employ[index].salary, pRoll->employ[index].withhold)));
    			fflush(stdout);
    		}	else {
    			printf("%s\t\t\t\t\t%.2lf\t-\t%.2lf\t\t%.2lf\n", (pRoll->employ[index].name), (pRoll->employ[index].salary), (calTax(pRoll->employ[index].salary, pRoll->employ[index].withhold)), (calNet(pRoll->employ[index].salary, pRoll->employ[index].withhold)));
    			fflush(stdout);
    		}
    	}
    }
    
    char *retNew(char *str1, char *str2, int space){
    	char *strNew = malloc(strlen(str1) + strlen(str2) + 1 * sizeof(char));
    	strNew = strcpy(strNew, str1);
    	if(space == 0){
    		strNew = strcat(strNew, str2);
    		return strNew;
    	} else {
    		char *sp = " ";
    		strNew = strcat(strNew, sp);
    		strNew = strcat(strNew, str2);
    		return strNew;
    	}
    }

IMN logo majestic logo threadwatch logo seochat tools logo