Remove gradebook name

I have this code that uses gradebook and student files to create a gradebook and stores student names and grades. When launching the file is asks for a name for the gradebook and uses that information to do the rest of the program. I want to remove that, so it doesn't ask for a name for the gradebook, but instead just has a standard name for the gradebook and does the rest by reference. How would I go about doing this? Is there anyway to remove the enum global constants as well? Also any tips for improving the code or making it look better would be appreciated!
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
//Source.cpp
#include <iostream>
#include <string>
#include "Gradebook.h"

//Global declarations: Constants and type definitions only -- NO variables
enum choices
{
	ADD, LIST, QUIT
};

//Function prototypes
void ChoiceMenu(choices menuChoice, Gradebook& gbook);
choices getChoice(bool& bquit);

int main()
{
	//Variable declarations
	std::string gname;
	bool quit = false; // looping bool

	//Program logic
	std::cout << "Please enter a name for your gradebook with no spaces: " << std::endl;

	std::cin >> gname;

	Gradebook g1(gname);

	do
	{
		std::cout << "List of Options:\nAdd (A):\nList (L):\nQuit (Q):\nChoice:";

		ChoiceMenu(getChoice(quit), g1); // gets user choices, flips bool on QUIT, and gives access to each feature A, L, Q
	} while (!quit); // quit is negated because in functions it is used in, it's more readable to have it become true rather than become false


	//Closing program statements
	system("pause");
	return 0;
}

//Function definitions

void ChoiceMenu(choices menuChoice, Gradebook& gbook) // reference to make sure gradebook can be changed within scope of other functions
{
	switch (menuChoice)
	{
	default:
		break;
	case ADD:
		if (gbook.GetNumStudents() < 3)
		{
			std::string studentName;

			std::cout << "Enter last name:" << std::endl;

			std::cin >> studentName;

			gbook.AddStudent(studentName);
		}
		else
		{
			std::cout << "There are already 3 students in the gradebook." << std::endl;
		}
		break;

	case LIST:
		if (gbook.GetNumStudents() == 0)
		{
			std::cout << "There are no students in the gradebook." << std::endl;
		}
		else
		{
			gbook.PrintAllRecords();
		}
			break;

	case QUIT:
		// getChoice already flips this bool, ending the loop. Leaving case to prevent ambiguity and misunderstanding.
		break;
	}
}

choices getChoice(bool& bquit)
{
	char userChoice;

	std::cin >> userChoice;

	if (userChoice == 'a' || userChoice == 'A')
	{
		return ADD;
	}
	else if (userChoice == 'l' || userChoice == 'L')
	{
		return LIST;
	}
	else if (userChoice == 'q' || 'Q')
	{
		bquit = true;
		return QUIT;
	}
	return choices();
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
// Gradebook.h
#pragma once

#include <string>
#include <vector>
#include "Student.h"


class Gradebook
{
private:
	std::vector<Student> gradebook;
	std::string gradebookName;

public:
	Gradebook(std::string name); // initializes to gradebook name

	// Setters
	void SetgradebookName(std::string name);

	// Getters
	std::string GetgradebookName();
	int GetNumStudents();

	// Operations
	void AddStudent(std::string studentName);
	void PrintAllRecords();

};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
//Gradebook.cpp
#include "string"
#include "Gradebook.h"

Gradebook::Gradebook(std::string name)
{
	SetgradebookName(name);
}

void Gradebook::SetgradebookName(std::string name)
{
	gradebookName = name;
}

std::string Gradebook::GetgradebookName()
{
	return gradebookName;
}

int Gradebook::GetNumStudents()
{
return gradebook.size();
}

void Gradebook::AddStudent(std::string studentName)
{
	Student student(studentName); // creates object with studentName parameter

	student.AddMultipleGrades(); // gets multiple grades for student

	gradebook.push_back(student); // inserts object into gradebook
}

void Gradebook::PrintAllRecords()
{
	for (Student i : gradebook) // calls print on each obj in the array
	{
		i.DisplayGrades();
	}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
//Student.h
#pragma once


#include <iostream>
#include <vector>
#include <string>

class Student
{
private:
	// Vars
	std::vector<double> grades;
	std::string lName;
	int numGrades = 5;

	// Operations
	void AddGrade(int grade);

public:
	Student(std::string name); // inits object to given name, and array of grades

	// Setters
	void SetlName(std::string name);

	// Getters
	std::string GetlName();

	// Operations
	void DisplayGrades();
	void AddMultipleGrades();



};

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
//Student.cpp
#include "string"
#include "Student.h"

Student::Student(std::string name)
{
	SetlName(name);
}

void Student::SetlName(std::string name)
{
	lName = name;
}

std::string Student::GetlName()
{
	return lName;
}

void Student::DisplayGrades()
{
	std::cout << lName << "'s grades are: " << std::endl;
	for (int i : grades) // prints each grade in array
	{
		std::cout << i << std::endl;
	}
}

void Student::AddMultipleGrades()
{
	int grade;


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

		std::cin >> grade;

		if (grade == -1) // stops asking for grades if input is -1
		{
			break;
		}

		AddGrade(grade);
	}
}

void Student::AddGrade(int grade) // adds grade to array
{
	grades.push_back(grade);
}
Last edited on
do you want the same name every time or a standard pattern?
you stop asking user and hard code it in a constant, and if its a pattern append to that, eg:

const string pattern = "filenamepattern";
...
static int num = 1000;
string gname = pattern+stoi(num++)+".dat";
Gradebook g1(gname);

//first one will be filenamepattern1000.dat, second will be filenamepattern1001.dat .. etc
Same name every time. I would do this in both the Gradebook.cpp and .h correct?
Last edited on
in main, line 19: std::string gname = "The_File_Name.dat";

in main, delete lines 23 1 25;

Now you aren't bugging the user for the file name any more.

I would suggest making the string file name a constant, so it can't be altered:

const std::string gname = "The_File_Name.dat";
Last edited on
I did that, now when I run the code It won't go past adding a name to the gradebook. I enter the name and hit "enter" and it won't continue the loop.
Ok So I changed my Source file a little bit. All of my "gbook." is getting undefined. Im not sure how to identify it so it runs correctly. Is there a problem with how I set up my switch?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#include <iostream>
#include <string>
#include "Gradebook.h"

int main()
{
	//Variable declarations
	const std::string gname = "Gradebook.dat";
	Gradebook g(gname);
	char userChoice;
	
	while (1)
	{
		std::cout << "List of Options:\nAdd (A):\nList (L):\nQuit (Q):\nChoice:";

		switch (userChoice) // reference to make sure gradebook can be changed within scope of other functions
		{
			std::cin >> userChoice;
			
		default:

			std::cout << "That is not a valid option, please enter 'A' to add a student, 'L' to list current students, or 'Q' to quit the program." << std::endl;
			break;

		case 'A':
			if (userChoice == 'a' || userChoice == 'A' || gbook.GetNumStudents() < 3)
			{
				std::string studentName;

				std::cout << "Enter last name:" << std::endl;

				std::cin >> studentName;

				gbook.AddStudent(studentName);
			}
			else (userChoice == 'a' || userChoice == 'A' || gbook.GetNumStudents() > 3);
			{
				std::cout << "There are already 3 students in the gradebook." << std::endl;
			}
			break;

			case 'L':
			if (userChoice == 'l' || userChoice == 'L')
			{
				gbook.PrintAllRecords();
				
			}
			else (gbook.GetNumStudents() == 0);
			{
				std::cout << "There are no students in the gradebook." << std::endl;
			}
			break;

		case 'Q':
			if ((userChoice == 'q' || 'Q'))
			{
				std::cout << "Thank you for using the Gradebook! Now exiting.." << std::endl;
				// getChoice already flips this bool, ending the loop. Leaving case to prevent ambiguity and misunderstanding.
				exit(1);
			}
			
			
		}
	}
}
Last edited on
Nothing in your code declares anything called gbook. On line 9, you declare something called g. Is it supposed to be that?

EDIT: I have to ask - why didn't you look for that? Surely, if you get an error saying a symbol is undefined, the very first thing you would think of doing is looking for the definition, and confirming whether there is or ism't one?
Last edited on
Topic archived. No new replies allowed.