8 Replies - 5402 Views - Last Post: 07 November 2010 - 07:11 PM Rate Topic: -----

#1 jrayos  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 21-September 10

Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 03:27 PM

Hello, I am having trouble with an assignment. I have written my structure, now all i need to do is write a function that will either store or discard information based on the batting average of a player. I don't really know where to get started on the function, any help would be great. Thanks!


This is the assignment:


Define a structure called BasballPlayer with the following members:
Team
Number (number worn on the uniform)
First name
Last name
Position
Batting Average (double)

Write a program that defines an array of pointers to objects of type BaseballPlayer. Enter all the above information from the keyboard for each player. If the player’s Batting Average is at least .275, call a function, MakePlayer(). This function must dynamically allocate memory for an object of type BaseballPlayer, store the values in the object, and return a pointer to the object. Then have the next available pointer in the array point to that object. If the player’s average is lower than .275 discard and input another player. Input “end” for Team as a sentinel value (Hint: strcmp()).



And my code so far( i know there are some useless parts, they will be used later):


#include <stdio.h>

typedef struct BaseballPlayer {
	int Number;
	char FirstName[25];
	char LastName[25];
	char Team[25];
	double BattingAverage;
};

/* Function Prototypes */
void Sort( struct BaseballPlayer list[], int size );
void Print( struct BaseballPlayer list[], int size );
double Average( struct BaseballPlayer list[], int size );

int main() 
{
	/* declare and initialize variables */
	int size = 10, i = 0;
	double average = 0.0;
	struct BaseballPlayer list[10];

	printf("Enter a Number: ");
	scanf("%d", &list[i].Number);

	while (i < 10 && list[i].Number != -1)
	{
		printf("Enter a First Name: ");
		scanf("%s", &list[i].FirstName);
		printf("Enter a Last Name: ");
		scanf("%s", &list[i].LastName);
		printf("Enter a Team: ");
		scanf("%s", &list[i].Team);
		printf("Enter a Batting Average: ");
		scanf("%lf", &list[i].BattingAverage);
		printf("-------------------------------\n");
		i++;

		printf("Enter a Number: ");
		scanf("%d", &list[i].Number);
	}
	Sort( list, i );
	printf("-------------------------------\n\n");
	Print( list, i );
	printf("-------------------------------\n\n");
	average = Average( list, i );
	printf("The average Batting Average is %5.3f\n", average);
	printf("-------------------------------\n\n");

return;
}

void Sort( struct BaseballPlayer list[], int size )
{
	int min = 0, i = 0, j = 0;
	struct BaseballPlayer temp;

	for( i = 0; i < size; i++ )
	{
		min = i;
		for( j = i + 1; j < size; j++ )
		{
			if( strcmp(list[j].LastName, list[min].LastName) < 0 )
			{
				min = j;
			}
		}
		if( min != i )
		{
			temp = list[min];
			list[min] = list[i];
			list[i] = temp;
		}
	}

	return;
}

void Print( struct BaseballPlayer list[], int size )
{
	int i = 0;
	for( i = 0; i < size; i++ )
	{
		printf("%5d %10s %10s %15s %5.3f \n", list[i].Number, list[i].FirstName, list[i].LastName, list[i].Team, list[i].BattingAverage);
	}

	return;
}

double Average( struct BaseballPlayer list[], int size )
{
	int i = 0;
	double sum = 0.0;

	for( i = 0; i < size; i++ )
	{
		sum += list[i].BattingAverage;
	}

	return sum/i;

}




Is This A Good Question/Topic? 0
  • +

Replies To: Array of Pointers- dynamic memory allocation

#2 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4333
  • View blog
  • Posts: 12,128
  • Joined: 18-April 07

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 06:18 PM

Wow jrayos, some bad news for you here. Hopefully you didn't take too long to write all this but you should have read the directions a little better. The first line of the instructions told you to create an "array of pointers to objects of type BaseballPlayer". By defining the array as struct BaseballPlayer list[10]; this is not an array of pointers. This is actually an array of structures, not pointers to those structures. This means you have to redefine the array and change a bit of every function you wrote. You won't be accessing an array element as list[i].team, you would be accessing it as list[i]->team.

I think I can help make the needed changes real quick... but the idea for your MakePlayer function is that once you have collected the info, pass it to the function and it will create a new player using the "new" keyword and assign it to the appropriate spot in the array.

With this array you will also need to make sure you clean up by using the keyword "delete".

Here is the code with the necessary changes (not complete though, so make sure you go through and see what is being done and finish it up).

#include <stdio.h>
#include <string.h>

typedef struct BaseballPlayer {
	int Number;
	char FirstName[25];
	char LastName[25];
	char Team[25];
	double BattingAverage;
};

/* Function Prototypes */
// Notice passing lists of pointers
void Sort( struct BaseballPlayer *list[], int size );
void Print( struct BaseballPlayer *list[], int size );
double Average( struct BaseballPlayer *list[], int size );
BaseballPlayer* MakePlayer(int playerNum, char playerFirstName[], char playerLastName[], char playerTeam[], double avg);

int main() 
{
	/* declare and initialize variables */
	int size = 10, i = 0;

	// Store variables for input
	int playnum = 0;
	char first_name[25];
	char last_name[25];
	char team_name[25];
	double batting_avg = 0.0;

	double average = 0.0;

	// Array of pointers to BaseballPlayer structs
	struct BaseballPlayer *list[10];

	printf("Enter a Number: ");
	scanf("%d", &playnum);

	// Read your directions again about the condition needed to end the loop (sentinel value of "end" for team, not player num)
	while (i < 10 && playnum != -1)
	{
		// Collect the info into our variables
		printf("Enter a First Name: ");
		scanf("%s", &first_name);
		printf("Enter a Last Name: ");
		scanf("%s", &last_name);
		printf("Enter a Team: ");
		scanf("%s", &team_name);
		printf("Enter a Batting Average: ");
		scanf("%lf", &batting_avg);
		printf("-------------------------------\n");

		// Compare the batting average to see if they make the team roster.
		// Put in the next available index and increment the value.
		if (batting_avg >= .275) {
			list[i] = MakePlayer(playnum, first_name, last_name, team_name, batting_avg);
			i++;
		}
		else { 
			// Didn't make it, so don't increment and go back around for another player.
			printf("Sorry, but that player was not good enough to make the team. Enter another.");
		}

		printf("Enter a Number: ");
		scanf("%d", &playnum);
	}
	Sort( list, i );
	printf("-------------------------------\n\n");
	Print( list, i );
	printf("-------------------------------\n\n");
	average = Average( list, i );
	printf("The average Batting Average is %5.3f\n", average);
	printf("-------------------------------\n\n");


	// Loop through and delete our objects.
	for (int i = 0; i < size; i++) {
		if (list[i] != NULL) { delete list[i]; }
	}

    return 0;
}

void Sort( struct BaseballPlayer *list[], int size )
{
	int min = 0, i = 0, j = 0;
	struct BaseballPlayer *temp;

	for( i = 0; i < size; i++ )
	{
		min = i;
		for( j = i + 1; j < size; j++ )
		{
			if( strcmp(list[j]->LastName, list[min]->LastName) < 0 )
			{
				min = j;
			}
		}
		if( min != i )
		{
			temp = list[min];
			list[min] = list[i];
			list[i] = temp;
		}
	}

	return;
}

void Print( struct BaseballPlayer *list[], int size )
{
	int i = 0;
	for( i = 0; i < size; i++ )
	{
		printf("%5d %10s %10s %15s %5.3f \n", list[i]->Number, list[i]->FirstName, list[i]->LastName, list[i]->Team, list[i]->BattingAverage);
	}

	return;
}

double Average( struct BaseballPlayer *list[], int size )
{
	int i = 0;
	double sum = 0.0;

	for( i = 0; i < size; i++ )
	{
		sum += list[i]->BattingAverage;
	}

	return sum/i;

}


// Notice return type is a pointer
BaseballPlayer* MakePlayer(int playerNum, char playerFirstName[], char playerLastName[], char playerTeam[], double avg) {

	// Construct a player
	// copy over the data and return this pointer
	BaseballPlayer *player = new BaseballPlayer();
	player->Number = playerNum;
	strcpy(player->FirstName, playerFirstName);
	strcpy(player->LastName, playerLastName);
	strcpy(player->Team, playerTeam);
	player->BattingAverage = avg;

	return player;
}



So as you will see the list has been setup as an array of pointers. Our MakePlayer() function takes in the values of a player, constructs the object and returns it as a pointer. We use this to then stash in the array.

Make sure you read your instructions again because your while loop is not looking for the right sentinel value and you can change around the loop a little because right now you have it asking for an extra player number. So it is prompting for a number 11 times for creating 10 players.

Good luck and read the in code comments. :)

This post has been edited by Martyr2: 07 November 2010 - 06:25 PM

Was This Post Helpful? 0
  • +
  • -

#3 jrayos  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 21-September 10

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 06:29 PM

Amazing Help! Thank you so much for taking the time. I really appreciate it!

-Jon
Was This Post Helpful? 0
  • +
  • -

#4 jrayos  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 21-September 10

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 06:48 PM

Ok, one final question:

I need to sort the list and my function is getting a error saying: temp undeclared.. first use this function.



#include <stdio.h>
#include <string.h>

typedef struct BaseballPlayer {
	int Number;
	char FirstName[25];
	char LastName[25];
	char Team[25];
	double BattingAverage;
	

struct BaseballPlayer *temp[1]; 

};

/* Function Prototypes */
// Notice passing lists of pointers
void Sort( struct BaseballPlayer *list[], int size );
void Print( struct BaseballPlayer *list[], int size );
double Average( struct BaseballPlayer *list[], int size );
BaseballPlayer* MakePlayer(int playerNum, char playerFirstName[], char playerLastName[], char playerTeam[], double avg);
void sortRoster(struct BaseballPlayer *list[], int size, int length);

int main() 
{
	/* declare and initialize variables */
	int size = 10, i = 0;
    int length = 0;
	// Store variables for input
	int playnum = 0;
	char first_name[25];
	char last_name[25];
	char team_name[25];
	double batting_avg = 0.0;

	double average = 0.0;

	// Array of pointers to BaseballPlayer structs
	struct BaseballPlayer *list[10];

	printf("Enter a Team: ");
	scanf("%d", &team_name);

	// Read your directions again about the condition needed to end the loop (sentinel value of "end" for team, not player num)
	while (i < 25 && team_name != "end")
	{
		// Collect the info into our variables
		printf("Enter a First Name: ");
		scanf("%s", &first_name);
		printf("Enter a Last Name: ");
		scanf("%s", &last_name);
		printf("Enter a Team: ");
		scanf("%s", &team_name);
		printf("Enter a Batting Average: ");
		scanf("%lf", &batting_avg);
		printf("-------------------------------\n");

		// Compare the batting average to see if they make the team roster.
		// Put in the next available index and increment the value.
		if (batting_avg >= .275) {
			list[i] = MakePlayer(playnum, first_name, last_name, team_name, batting_avg);
			i++;
		}
		else { 
			// Didn't make it, so don't increment and go back around for another player.
			printf("Sorry, but that player was not good enough to make the team. Enter another.");
		}

		printf("Enter a Number: ");
		scanf("%d", &playnum);
	}


	/*sortRoster(list, i, length);
	*/
	Print( list, i );


	// Loop through and delete our objects.
	for (int i = 0; i < 10; i++) {
		if (list[i] != NULL) { delete list[i]; }
	}

    return 0;
}


void Print( struct BaseballPlayer *list[], int size )
{
	int i = 0;
	for( i = 0; i < size; i++ )
	{
		printf("%5d %10s %10s %15s %5.3f \n", list[i]->Number, list[i]->FirstName, list[i]->LastName, list[i]->Team, list[i]->BattingAverage);
	}

	return;
}




// Notice return type is a pointer
BaseballPlayer* MakePlayer(int playerNum, char playerFirstName[], char playerLastName[], char playerTeam[], double avg) {

	// Construct a player
	// copy over the data and return this pointer
	BaseballPlayer *player = new BaseballPlayer();
	player->Number = playerNum;
	strcpy(player->FirstName, playerFirstName);
	strcpy(player->LastName, playerLastName);
	strcpy(player->Team, playerTeam);
	player->BattingAverage = avg;

	return player;
}


void sortRoster(struct BaseballPlayer *list[], int size, int length)

{

 

      //define function variables

      int i = size;

      int j;
      
  

      //sort by batting average

      for(i = 0; i < length; i++)

      {

            for(j = i + 1; j < length; j++)

            {

                  if(list[i]->BattingAverage < list[j]->BattingAverage)

                  {

                        temp[i] = list[i];

                        list[i] = list[j];

                        list[j] = temp[i];

                  }

            }

      }

}




Thanks!
Was This Post Helpful? 0
  • +
  • -

#5 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4333
  • View blog
  • Posts: 12,128
  • Joined: 18-April 07

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 06:55 PM

No no.. what are you doing?! You had a sort function in there called Sort and it was sorting just fine. Why are you putting in this sortRoster? It was sorting the roster already. Did you have to sort on a different field or something?

Also look at your sortRoster function you created... in it you are using temp[i]. Where in that function did you define it? Look back at your original sort function in there it will show you that temp is declared before being used.

:dontgetit:

P.S. Go back to your original sort function and look at how it is put together. Sorting on a different field will only require a *minor* change of what you compare

This post has been edited by Martyr2: 07 November 2010 - 06:58 PM

Was This Post Helpful? 0
  • +
  • -

#6 jrayos  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 21-September 10

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 06:56 PM

ok ok, thank you lol im bad at this!
Was This Post Helpful? 0
  • +
  • -

#7 jrayos  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 21-September 10

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 07:02 PM

The only problem is that i need it to sort by batting average, not by last name and when i change it it gives the error: 95 C:\Users\Jon\Desktop\wk11retake.cpp cannot convert `double' to `const char*' for argument `1' to `int strcmp(const char*, const char*)'


#include <stdio.h>
#include <string.h>

typedef struct BaseballPlayer {
	int Number;
	char FirstName[25];
	char LastName[25];
	char Team[25];
	double BattingAverage;
	


};

/* Function Prototypes */
// Notice passing lists of pointers
void Sort( struct BaseballPlayer *list[], int size );
void Print( struct BaseballPlayer *list[], int size );
double Average( struct BaseballPlayer *list[], int size );
BaseballPlayer* MakePlayer(int playerNum, char playerFirstName[], char playerLastName[], char playerTeam[], double avg);


int main() 
{
	/* declare and initialize variables */
	int size = 10, i = 0;
    int length = 0;
	// Store variables for input
	int playnum = 0;
	char first_name[25];
	char last_name[25];
	char team_name[25];
	double batting_avg = 0.0;

	double average = 0.0;

	// Array of pointers to BaseballPlayer structs
	struct BaseballPlayer *list[10];

	printf("Enter a Team: ");
	scanf("%d", &team_name);

	// Read your directions again about the condition needed to end the loop (sentinel value of "end" for team, not player num)
	while (i < 25 && team_name != "end")
	{
		// Collect the info into our variables
		printf("Enter a First Name: ");
		scanf("%s", &first_name);
		printf("Enter a Last Name: ");
		scanf("%s", &last_name);
		printf("Enter a Team: ");
		scanf("%s", &team_name);
		printf("Enter a Batting Average: ");
		scanf("%lf", &batting_avg);
		printf("-------------------------------\n");

		// Compare the batting average to see if they make the team roster.
		// Put in the next available index and increment the value.
		if (batting_avg >= .275) {
			list[i] = MakePlayer(playnum, first_name, last_name, team_name, batting_avg);
			i++;
		}
		else { 
			// Didn't make it, so don't increment and go back around for another player.
			printf("Sorry, but that player was not good enough to make the team. Enter another.");
		}

		printf("Enter a Number: ");
		scanf("%d", &playnum);
	}

    Sort( list, i );

	Print( list, i );


	// Loop through and delete our objects.
	for (int i = 0; i < 10; i++) {
		if (list[i] != NULL) { delete list[i]; }
	}

    return 0;
}

void Sort( struct BaseballPlayer *list[], int size )
{
	int min = 0, i = 0, j = 0;
	struct BaseballPlayer *temp;

	for( i = 0; i < size; i++ )
	{
		min = i;
		for( j = i + 1; j < size; j++ )
		{
			if( strcmp(list[j]->BattingAverage, list[min]->BattingAverage) < 0 )
			{
				min = j;
			}
		}
		if( min != i )
		{
			temp = list[min];
			list[min] = list[i];
			list[i] = temp;
		}
	}

	return;
}

void Print( struct BaseballPlayer *list[], int size )
{
	int i = 0;
	for( i = 0; i < size; i++ )
	{
		printf("%5d %10s %10s %15s %5.3f \n", list[i]->Number, list[i]->FirstName, list[i]->LastName, list[i]->Team, list[i]->BattingAverage);
	}

	return;
}




// Notice return type is a pointer
BaseballPlayer* MakePlayer(int playerNum, char playerFirstName[], char playerLastName[], char playerTeam[], double avg) {

	// Construct a player
	// copy over the data and return this pointer
	BaseballPlayer *player = new BaseballPlayer();
	player->Number = playerNum;
	strcpy(player->FirstName, playerFirstName);
	strcpy(player->LastName, playerLastName);
	strcpy(player->Team, playerTeam);
	player->BattingAverage = avg;

	return player;
}



Was This Post Helpful? 0
  • +
  • -

#8 Martyr2  Icon User is offline

  • Programming Theoretician
  • member icon

Reputation: 4333
  • View blog
  • Posts: 12,128
  • Joined: 18-April 07

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 07:06 PM

strcmp is for strings, batting average are doubles... compare them directly...


if (list[j]->BattingAverage < list[min]->BattingAverage) {



;)

This post has been edited by Martyr2: 07 November 2010 - 07:07 PM

Was This Post Helpful? 0
  • +
  • -

#9 jrayos  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 28
  • Joined: 21-September 10

Re: Array of Pointers- dynamic memory allocation

Posted 07 November 2010 - 07:11 PM

Thanks! Everything compiles, but when you enter a team name as the first input, it messes up. Sorry if the problem is obvious.. lol
Was This Post Helpful? 0
  • +
  • -

Page 1 of 1