I am having problems with dynamically allocating an array of structures. I have to write a program that ask for how many students a teacher has and then create an array of structures to fit that request. My complier compiles but when I run the prgm I get a runtime error and the prgm freezes.
#include<limits>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<string>
#include<vector>
#include<ctime>
#include<iomanip>
#include <algorithm>
#include<fstream>
#include<conio.h>
usingnamespace std;
bool inputGood = false; //global variable used to validate input;
int numberStudents(int); //prototype for function that gets the number of students from user
int numberTests(int); //prototype for function that gets the number of tests from user
//a strucure to be used as a data type to hold a student's info
struct StudentInfo
{
string name; //member to hold name of a student
string idNumber; //member to hold students id number
int *testScores; //pointer member to hold students test grades
double averageOfTests; //member to hold the average of the students test grades
char courseGrade; //member to hold the letter grade for the student
};
int main()
{
int numStudents; //variable to hold the number of students input by user
int numTests; //variable to hold the number of tests
numStudents = numberStudents(numStudents);
numTests = numberTests(numTests);
StudentInfo *student[numStudents];
student[numStudents] = new StudentInfo;
for(int i = 0; i < numStudents; i++)
{
cout << "What is student number " << (i+1) << "'s name";
cin.ignore();
getline(cin, student[i]->name);
}
//delete [] student;
return 0;
}
//function to get the number of students
int numberStudents(int numberOfStudents)
{
do
{
cout << "How many students do you have to enter information on? ";
inputGood = std::cin >> numberOfStudents;
if(numberOfStudents <= 0 || !inputGood)
{
cout << "Invalid Entry!" << endl;
cin.clear();
while( cin.get() != '\n' );
}
}while(numberOfStudents <= 0 || !inputGood);
system("cls");
return numberOfStudents;
}
//function to get the number of tests for each student
int numberTests(int numberOfTests)
{
do
{
cout << "How many tests does each student have? ";
inputGood = std::cin >> numberOfTests;
if(numberOfTests <= 0 || !inputGood)
{
cout << "Invalid Entry!" << endl;
cin.clear();
while( cin.get() != '\n' );
}
}while(numberOfTests <= 0 || !inputGood);
system("cls");
return numberOfTests;
}
StudentInfo *student[numStudents];
student[numStudents] = new StudentInfo;
Line 40 there doesn't do what you might think it does.
Rather than initializing each item in the student array with a new StudentInfo structure, it gives the array element at index numStudents (which is out-of-bounds) a new StudentInfo.
It's kinda like this:
1 2
int array[5];
array[5] = 4; // Assigning a value to an out-of-bounds element
So you'll need to use a loop.
Eh, or see giblit's post.
(That code isn't even valid anyways since arrays on the stack have to have a constant size.)
int numberStudents(int numberOfStudents) and int numberTests(int numberOfTests) are identical, but for the prompt. The code can be factored into a single function, with the prompt as a parameter.
#include<limits>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<string>
#include<vector>
#include<ctime>
#include<iomanip>
#include <algorithm>
#include<fstream>
//#include<conio.h>
usingnamespace std;
//bool inputGood = false; //global variable used to validate input;
// int numberStudents(int); //prototype for function that gets the number of students from user
// int numberTests(int); //prototype for function that gets the number of tests from user
int get_positive_number( std::string prompt ) ;
//a strucure to be used as a data type to hold a student's info
struct StudentInfo
{
string name; //member to hold name of a student
string idNumber; //member to hold students id number
//int *testScores; //pointer member to hold students test grades
vector<int> testScores ;
double averageOfTests; //member to hold the average of the students test grades
char courseGrade; //member to hold the letter grade for the student
};
int main()
{
// int numStudents; //variable to hold the number of students input by user
// int numTests; //variable to hold the number of tests
constint numStudents = get_positive_number( "number of students? " );
constint numTests = get_positive_number( "number of tests? " );
// StudentInfo *student[numStudents];
// student[numStudents] = new StudentInfo;
vector<StudentInfo> student(numStudents) ;
for(int i = 0; i < numStudents; i++)
{
cout << "What is student number " << (i+1) << "'s name? ";
cin.ignore();
//getline(cin, student[i]->name);
getline(cin, student[i].name);
student[i].testScores.resize(numTests) ;
// ...
}
//delete [] student;
// return 0;
}
int get_positive_number( std::string prompt )
{
bool inputGood = false ;
int value ;
do
{
cout << prompt ;
inputGood = std::cin >> value ;
if( value <= 0 || !inputGood )
{
cout << "Invalid Entry!" << endl;
cin.clear();
while( cin.get() != '\n' );
}
}while( value <= 0 || !inputGood );
// system("cls");
return value ; // numberOfStudents;
}
I have made the suggested fixes that JLBorges suggested. But now I am having problems inputting data into the dynamically allocated array within the structure I have tried using the -> dereference operator and still no luck.
#include<limits>
#include<iostream>
#include<cmath>
#include<cstdlib>
#include<string>
#include<vector>
#include<ctime>
#include<iomanip>
#include <algorithm>
#include<fstream>
#include<conio.h>
usingnamespace std;
bool inputGood = false; //global variable used to validate input;
//protype to retrieve a positive number
int poitiveNumber(string);
//a strucure to be used as a data type to hold a student's info
struct StudentInfo
{
string name; //member to hold name of a student
string idNumber; //member to hold students id number
int *testScores; //pointer member to hold students test grades
double averageOfTests; //member to hold the average of the students test grades
char courseGrade; //member to hold the letter grade for the student
};
int main()
{
//variable to hold the number of students input by user
constint numStudents = poitiveNumber("Number of students? ");
//variable to hold the number of tests
constint numTests = poitiveNumber("Number of tests? ");
int i; //variable to use to iterate the first for loop
StudentInfo *student = new StudentInfo[numStudents];
for(i = 0; i < numStudents; i++)
{
cout << "What is student number " << (i+1) << "'s name? ";
cin.ignore();
getline(cin, student[i].name);
cout << "What is " << student[i].name << "'s id number? ";
cin >> student[i].idNumber;
for(int x = 0; x < numTests; x++)
{
cout << "What is " << student[i].name << "'s number "
<< (x+1) << " test score";
cin >> student[i].testScores[x];
}
}
delete [] student;
return 0;
}
//function to get a positive number
int poitiveNumber(string prompt)
{
int pNum;
do
{
cout << prompt;
inputGood = std::cin >> pNum;
if(pNum <= 0 || !inputGood)
{
cout << "Invalid Entry!" << endl;
cin.clear();
while( cin.get() != '\n' );
}
}while(pNum <= 0 || !inputGood);
system("cls");
return pNum;
}
You forgot to allocate memory for the test scores. You are trying to assign a value to the pointer. Before line 52 you should put
student[i]->testScores = newint[numTests];
or if you can use vectors like JLBorges mentioned use them they are much better than using arrays like that. Since you forgot to allocate and deallocate both times :P
Thanks giblet. I would prefer vectors I believe they are easier to deal with and have many other prebuilt in functions that I could use. Im only stuck with following the prompt of my book. I did what you mentioned except that I had to utilize the dot(.) operator other than the dereference operator(->) other than that it seems to work so far. I will be finishing this prgm today before I go to sleep I hope. I having only been coding for 6 months now so I still have much to learn.
The reason why I have all the libraries is they are in my basic_program_model I use when I build prgms. I eliminate the ones I don't use when im done coding the prgm