New to C++, modules and switch menu - c++

I am working on a project that involves creating a menu screen, and integrating three programs into one that can be selectively launched from the menu screen.
I thought making individual programs first before piecing them together with switch case and functions would be easy (I don't know class/objects). I keep running into a brick wall and a host of syntax/logical errors, so I deleted everything and now I'm back to square one-- with three distinct programs. This is very daunting-- how do proceed? :/
#include <iostream>
using namespace std;
int main ()
{
int x;
cout << "Enter the amount of money you have ";
cin >> x;
if (x >= 20) {
cout << "You can buy Comic Book $1 or Sports Journal $3 or Science Book $15 or Third Volume Series $20";
} else if (x >= 15 && x < 20) {
cout << "You can buy Comic Book $1 or Sports Journal $3 or Science book $15";
} else if (x >= 3 && x < 15) {
cout << "You can buy Comic Book $1 or Sports Journal $3";
} else if (x >= 1 && x < 3) {
cout << "You can buy Comic Book $1";
} else if (x <= 0) {
cout << "You cannot afford anything";
}
return 0;
}
#include <iostream>
#include <iomanip>
#include <fstream>
using namespace std;
int main()
{
int numclass; //number of classes
int numStudents; //number of students
int numTests; // Number of tests per student
double sectiontotal; //Accumulator for Class total scores
double total; // Accumulator for total scores
double average; //Average test score
double totalaverage = 0;
ofstream outfile;
outfile.open("Gradesinfo.txt");
// Set up numeric output formatting.
cout << fixed << showpoint << setprecision(1);
// Get the number of students.
cout << "This program gives average of test scores per student, per class, and for the whole institution for upto 2 students in upto 2 different classes in 3 subjects\n";
// Determine each student's average score.
cout << "Enter the number of classes";
cin >> numclass;
cout << "Enter the number of students per class";
cin >> numStudents;
cout << "Enter the number of tests";
cin >> numTests;
for (int section = 1; section <= numclass; section++) {
sectiontotal = 0; //Initialize class accumulator
totalaverage = 0;
for (int student = 1; student <= numStudents; student++) {
total = 0; // Initialize the accumulator.
for (int test = 1; test <= numTests; test++) {
double score;
cout << "Enter score " << test << " for ";
cout << "student " << student << ": ";
cin >> score;
if (score >= 0 && score <= 100) {
total += score;
} else {
cout << "Enter value from 1 - 100" << endl;
test = test - 1;
}
}
average = total / numTests;
totalaverage += average;
cout << "The average score for student " << student;
cout << " is " << average << ".\n\n";
outfile << "The average score for student " << student;
outfile << " is " << average << ".\n\n";
}
cout << "The total average for class " << section << " is: " << totalaverage / numStudents << endl;
outfile << "The total average for class " << section << " is: " << totalaverage / numStudents << endl;
sectiontotal += totalaverage;
}
cout << "The total average for the institution is: " << sectiontotal / numclass;
outfile << "The total average for the institution is: " << sectiontotal / numclass;
outfile.close();
return 0;
}
#include<cstdlib>
#include<iostream>
#include<fstream>
using namespace std;
int main()
{
fstream instream;
ofstream outstream;
instream.open("Grades.txt");
if (instream.fail()) {
cout << "The input file failed to open\n";
exit(1);
}
int next, largest, smallest;
largest = 0;
smallest = 0;
while (instream >> next) {
if (largest < next) {
largest = next;
} else {
smallest = next;
}
}
cout << "The highest grade is: " << largest << endl;
instream.close();
system("pause");
return 0;
}

I think you are shooting yourself on the foot. go 1 step after the other, please do take this as reference:
create a main file as entry point for the app, note the prototype and implementation of the functions printA and printB
#include <iostream>
using namespace std;
void printA();
void printB();
int main()
{
int x = 1;
cout << "Enter the option:\n";
while (cin >> x)
{
if (x <= 0)
{
break;
}
switch (x) {
case 1:
printA();
break;
case 2:
printB();
break;
default:
cout << "Invalid";
}
}
return 0;
}
void printB()
{
cout << "B";
}
void printA()
{
cout << "A";
}
create a new file fooA.cpp and paste there the implemented function printA
do the same for the printB in another file.
remove those implementations from main.cpp
you are done!

Related

Output does not include all input for my array

I have this program that is barely started:
#include <iostream>
#include <iomanip>
#include <ctime>
#include <string>
using namespace std;
class Grade
{
public:
string studentID;
int userChoice = 0;
int size = 0;
double* grades = new double[size]{0};
};
void ProgramGreeting(Grade &student);
void ProgramMenu(Grade& student);
string GetID(Grade& student);
int GetChoice(Grade& student);
void GetScores(Grade& student);
int main()
{
Grade student;
ProgramGreeting(student);
ProgramMenu(student);
}
// Specification C1 - Program Greeting function
void ProgramGreeting(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << "Welcome to the GPA Analyzer! " << endl;
cout << "By: Kate Rainey " << endl;
cout << "Assignment Due Date: September 25th, 2022 " << endl;
cout << "--------------------------------------------" << endl;
GetID(student);
cout << "For Student ID # " << student.studentID << endl;
}
void ProgramMenu(Grade &student)
{
cout << "--------------------------------------------" << endl;
cout << setw(25) << "Main Menu" << endl;
cout << "1. Add Grade " << endl;
cout << "2. Display All Grades " << endl;
cout << "3. Process All Grades " << endl;
cout << "4. Quit Program." << endl;
cout << "--------------------------------------------" << endl;
GetChoice(student);
}
string GetID(Grade &student)
{
cout << "Enter the student's ID: ";
cin >> student.studentID;
if (student.studentID.length() != 8) {
cout << "Student ID's contain 8 characters ";
GetID(student);
}
return student.studentID;
}
int GetChoice(Grade &student)
{
cout << "Enter your selection: ";
cin >> student.userChoice;
if (student.userChoice == 1) {
GetScores(student);
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 2)
{
}
else if (student.userChoice == 4)
{
exit(0);
}
else
{
cout << "Please enter 1, 2, 3 or 4" << endl;
GetChoice(student);
}
}
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
for (int i = 0; i < student.size; i++) {
student.grades[i] = score;
}
count++;
}
for (int i = 0; i < student.size; i++) {
cout << student.grades[i] << " ";
}
}
I am trying to make sure my array is recording all test scores, but when I output the array in my GetScore function, each element in the array is the same or equal to the last score I entered. For example, if I choose 3 for size and then enter three values of 99.2 86.4 90.1, all three elements will read 90.1.
Why is this happening?
Your Grade class is allocating an array of 0 double elements (which is undefined behavior), and then your GetScores() function does not reallocate that array after asking the user how many scores they will enter, so you are writing the input values to invalid memory (which is also undefined behavior).
Even if you were managing the array's memory correctly (ie, by using std::vector instead of new[]), GetScores() is also running a for loop that writes the user's latest input value into every element of the array, instead of just writing it to the next available element. That is why your final output displays only the last value entered in every element. You need to get rid of that for loop completely.
Try something more like this instead (there are several other problems with your code, but I'll leave those as separate exercises for you to figure out):
class Grade
{
public:
...
int size = 0;
double* grades = nullptr;
};
...
void GetScores(Grade &student)
{
int size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
if (student.size != size) {
delete[] student.grades;
student.grades = new double[size]{0};
student.size = size;
}
for(int i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
for (int i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
Alternatively:
#include <vector>
...
class Grade
{
public:
...
vector<double> grades;
};
...
void GetScores(Grade &student)
{
size_t size = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# " << student.studentID << "? ";
cin >> size;
student.grades.resize(size);
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades[i] = score;
}
/* alternatively:
student.grades.clear();
for (size_t i = 0; i < size; ++i) {
cout << "Enter a grade: ";
cin >> score;
student.grades.push_back(score);
}
*/
for (size_t i = 0; i < size; ++i) {
cout << student.grades[i] << " ";
}
}
I removed my for loop from my while loop.
void GetScores(Grade &student)
{
int count = 0;
double score = 0;
cout << "How many test scores would you like to enter for ID# "
<< student.studentID << "? ";
cin >> student.size;
while (count != student.size) {
cout << "Enter a grade: ";
cin >> score;
student.grades[count] = score;
count++;
}
for (int j = 0; j < student.size; j++) {
cout << student.grades[j] << " ";
}
}

How can I store the random numbers outputed by my funtion?

at the moment I'm trying to add up the numbers for my hand and the hit cards, the issue is I created a function for my random number generator so that I can keep calling it into my dice game and the blackjack game, I would normally add the number generator to a variable and call it a day but I made it into a function instead. I am still new to c++.
#include <cstdlib>
#include <ctime>
#include <iostream>
using namespace std;
void RandomNumber() { cout << (rand() % 10) + 1; }
void blackjack(int total) {
int startstakes = 15;
int stakes;
int hand;
cout << "Welcome to the Blackjack(21) table\n"
<< "How much are you adding to your initial 15 chip stake - ";
cin >> stakes;
cout << "New stake - " << stakes + 15 << " remaining chips - "
<< total - (stakes + 15) << endl;
cout << "Here is your hand - ";
RandomNumber();
cout << " and ";
RandomNumber();
cout << "Hit me cards: 0 - 0 - 0\n"
<< "Total = ";
system("pause>0");
}
int main() {
int total = 0;
int choice;
srand((unsigned)time(NULL));
cout << "Welcome to Royal Casino!!!, How much money do you wish to "
"convert? ";
cin >> total;
cout << "Excelent you currently have " << total << " Chips.\n"
<< "Let's Begin!\n\n"
<< "We have to tables available today\n";
cout << "1) Blackjack (21)\n"
<< "2) Dice\n"
<< "Both have an entry fee of 15 Chips\n"
<< "Select a table - ";
cin >> choice;
if (choice == 1) {
blackjack(total);
}
if (choice == 2) {
dice();
}
system("pause");
}
So the issue is that you should return the value instead of printing it. Like this (note the return type has changed from void to int)
int RandomNumber() {
return (rand() % 10) + 1;
}
A function which returns a value is much more flexible than a function which prints a value.
Now you can use a function call RandomNumber() pretty much the same way as a variable. E.g.
cout << RandomNumber() << " and " << RandomNumber();
or
int var = RandomNumber();

How do I stop a sentinel value from being read into an array when determining total and average of the array?

I am not sure how to stop my sentinel value from being read into my array which is causing an error with my total and average calculation. Can anyone help?
Here is the while loop:
while (grade != -1)
{
cin >> grade;
gradesArray[count] = grade;
total += gradesArray[count];
average = total / count;
count++;
}
cout << "You have entered " << count << " grades." << endl;
cout << "The average of these grades is " << average << endl;
while (std::cin >> grade && grade != -1)
Here is my modified code, but the average outputs an average that is too high.
#include<iostream>
using namespace std;
int main()
{
int count = 0, grade = 0;
double total = 0, average;
const int numGrades = 20;
int gradesArray[numGrades];
cout << "Welcome to the grade calulator!" << endl;
cout << "Enter up to twenty grades, when done enter -1: " << endl;
while (cin >> grade && grade != -1)
{
gradesArray[count] = grade;
total += gradesArray[count];
average = total / count;
++count;
}
cout << "You have entered " << count << " grades." << endl;
cout << "The average of these grades is " << average << endl;
system("pause");
return 0;
}

(c++) reading from a text file

I made this program that asks users to enter the grade of some students, determine whether they pass or fail and then determine how many pass and how many fail the exam. Here's my code:
#include <iostream>
using namespace std;
int main ()
{
int passing = 0;
int failing = 0;
int mid_grade;
int final_grade;
int student = 5;
while (student > 0)
{
cout << "Enter mid-term grade: ";
cin >> mid_grade;
cout << "Enter final grade: ";
cin >> final_grade;
double total_grade = (double)mid_grade*3/10 + (double)final_grade*7/10;;
cout << "The total grade is: " << total_grade << endl;
student --;
if (mid_grade < 4 || final_grade < 4 || total_grade < 10)
{
// cout << "Fail." << endl;
failing++;
}
else
{
// cout << "Pass!" << endl;
passing++;
}
}
cout << passing << " student passed" << endl;
cout << failing << " student failed" << endl;
return 0;
}
what I want to do now is to tell my program to read the mid-term and the final grade in a text file I made then calculate the total grade (like I did in the above code), then show the grades on the screen, determine who pass and fail the exam and the total number of students who pass/fail the exam.
Here's what my text file looks like:
Mid-term Final
8 5
9 6
10 11
15 17
9 20
11 19
Alright so this should help. I put some notes. You need to create a text file in the same directory /src called grades.txt
should look like this
10 9 8 7 4 3 4 5 5 9
You will need to change things. But this should give you a good starting point or where you should be going. Hope this helps.
#include <iostream>
#include <fstream>
using namespace std;
int main ()
{
int passing = 0;
int failing = 0;
int mid_grade = 0; //Always initilize your variables!!!
int final_grade = 0;
int student = 5;
//Create a variable to open the file
ifstream inFile; inFile.open("src\\grades.txt");
while (student > 0)
{
cout << "Enter mid-term grade: ";
inFile >> mid_grade;
cout << mid_grade << endl;
cout << "Enter final grade: ";
inFile >> final_grade;
cout << final_grade << endl;
cout << "student number" << student << endl; //Notice it goes backwards you have to fix it.
double total_grade = ((double)mid_grade*3)/10 + ((double)final_grade*7/10);
cout << "The total grade is: " << total_grade << endl;
student --;
cout << endl;
if (total_grade < 7)
{
// cout << "Fail." << endl;
failing++;
}
else
{
// cout << "Pass!" << endl;
passing++;
}
}`enter code here`
cout << passing << " student penter code hereassed" << endl;
cout << failing << " student failed" << endl;
return 0;
}
I'd read the file, skip the 1st line, then read the rest, line by line, using stringtokenizer to get the two values to work with.

Writing rand() results to text file in C++ without repeating numbers

At this point in my program, I am writing for every time a random number is generated, the contents of that number in an array is written to a text file. The code:
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <time.h>
#include "inFrench.h"
using namespace std;
class student
{
int m_studentNumber;
public:
string nameFirst;
string nameLast;
string nameFull;
int getStudentNumber() { return m_studentNumber; }
void setStudentNumber(int studentNumber) { m_studentNumber = studentNumber; }
};
ostream& operator<<(ostream& os, const student& s)
{
return os << s.nameFirst << ' ' << s.nameLast;
}
student typeName()
{
student bar;
cout << "Type in a student's first name: ";
cin >> bar.nameFirst;
cout << "Type in that student's last name: ";
cin >> bar.nameLast;
bar.nameFull = bar.nameFirst + " " + bar.nameLast;
return bar;
}
void displayStudents(student listOfStudents[50], int studentHeadCount)
{
for (int i = 0; i < studentHeadCount; i++)
{
cout << listOfStudents[i].nameFull << endl;
cout << listOfStudents[i].getStudentNumber() << endl;
cout << "\n";
}
}
void generateGroups(int numberOfGroups, int maxStudents, int studentsPerGroup, int remainder, student theStudents[], int studentsBeenAssigned, ofstream studentGroups)
{
int k;
numberOfGroups = maxStudents / studentsPerGroup;
cout << numberOfGroups << endl;
srand(time(NULL));
studentGroups.open("studentGroups.txt");
while (studentsBeenAssigned < maxStudents && studentsBeenAssigned < maxStudents - remainder)
{
for (int j = 0; j < maxStudents - remainder; j++)
{
k = rand() % maxStudents;
cout << theStudents[k].nameFull << endl;
studentGroups << theStudents[k].nameFull << endl;
studentsBeenAssigned++;
if (studentsBeenAssigned == studentsPerGroup)
{
cout << "\n";
studentGroups << theStudents[k].nameFull << endl;
studentsBeenAssigned = 0;
}
}
}
if (remainder < studentsPerGroup && remainder > 0)
{
for (int l = 0; l < remainder; l++)
{
cout << theStudents[k].nameFull << endl;
}
}
}
void languageChoices()
{
cout << "Select your language from the following:\n";
cout << "a) English\n";
cout << "b) French\n";
cout << "\n";
}
void options()
{
cout << "Select what you want to do:\n";
cout << "1) Exit application\n";
cout << "2) Enter a Student\n";
cout << "3) Display Students\n";
cout << "4) Display Groups\n";
cout << "5) Output groups as text file\n";
cout << "6) Reset number of students in class\n";
cout << "7) Reset number of students per group\n";
cout << "\n";
}
int main()
{
char selectedLanguage;
languageChoices();
cin >> selectedLanguage;
switch (selectedLanguage)
{
case 'a':
{
student allStudents[50]; // Having 50 students alone is ridiculous!
bool endProg = 0;
int maxStudents;
int studentsPerGroup;
int optionSelect;
int studentHeadCount = 0;
int remainder = 0;
int numberOfGroups = 0;
int studentsBeenAssigned = 0;
ofstream studentGroups;
cout << "GroupPicker 1.0\n";
cout << "Note: This version of the program is intended for purposes of education only, "
<< "specifically for teacher use in a classroom.\n\n";
cout << "How many students are in the class?\n" << "(Note: You cannot have more than 50 in this program)\n";
cin >> maxStudents;
if (maxStudents > 50)
{
cerr << "Too many students!\n" << "Exiting program...\n";
system("PAUSE");
exit(1);
}
if (maxStudents >= 35 && maxStudents <= 50)
{
cout << maxStudents << " students? You are a pro!\n";
}
cout << "How many students per group?\n";
cin >> studentsPerGroup;
if (studentsPerGroup >= maxStudents || studentsPerGroup <= 1)
{
cerr << "You're kidding, right?\n" << "Exiting program...\n";
system("PAUSE");
exit(1);
}
while (endProg == 0) {
options();
cin >> optionSelect;
switch (optionSelect) {
case 1:
endProg = 1;
break;
case 2:
{
if (studentHeadCount == maxStudents)
{
cerr << "You can't enter more than " << maxStudents << " students\n";
}
else
{
allStudents[studentHeadCount] = typeName();
allStudents[studentHeadCount].setStudentNumber(studentHeadCount);
cout << "Student (" << allStudents[studentHeadCount].nameFull << ") entered.\n";
cout << "\n";
studentHeadCount++;
}
break;
}
case 3:
cout << "Current list of students:\n\n";
displayStudents(allStudents, studentHeadCount);
break;
case 4:
{
if (studentHeadCount < studentsPerGroup || studentHeadCount < maxStudents)
{
cerr << "Invalid group parameters.\n" << "Returning to main menu...\n\n";
break;
}
else
{
cout << "Here are the groups:\n\n";
studentGroups.open("studentGroups.txt");
generateGroups(numberOfGroups, maxStudents, studentsPerGroup, remainder, allStudents, studentsBeenAssigned, studentGroups);
}
break;
}
case 5:
{
cout << "Saving groups to file...\n";
studentGroups.close();
break;
}
case 6:
{
cout << "How many students are in the class?\n" << "(Note: You cannot have more than 50 in this program)\n";
cin >> maxStudents;
if (maxStudents > 50)
{
cerr << "Too many students!\n" << "Try again...\n";
}
if (maxStudents >= 35 && maxStudents <= 50)
{
cout << maxStudents << " students? You are a pro!\n";
}
break;
}
case 7:
{
cout << "How many students per group?\n";
cin >> studentsPerGroup;
if (studentsPerGroup >= maxStudents || studentsPerGroup <= 1)
{
cerr << "You're kidding, right?\n" << "Try again...\n";
}
break;
}
}
}
break;
}
case 'b':
{
mainInFrench();
}
}
}
When I compile, I get the following errors:
error C2248: 'std::basic_ofstream<_Elem,_Traits>::basic_ofstream' : cannot access private member declared in class 'std::basic_ofstream<_Elem,_Traits>'
IntelliSense: "std::basic_ofstream<_Elem, _Traits>::basic_ofstream(const std::basic_ofstream<_Elem, _Traits>::_Myt &_Right) [with _Elem=char, _Traits=std::char_traits<char>]" (declared at line 1034 of "C:\Program Files (x86)\Microsoft Visual Studio 11.0\VC\include\fstream") is inaccessible
How do I resolve these issues (Both on Line 181) and make sure that no number is generated more than once?
std::ofstream cannot be copied. It looks like you need a reference:
void generateGroups(int numberOfGroups, int maxStudents,
int studentsPerGroup, int remainder,
student theStudents[], int studentsBeenAssigned,
ofstream& studentGroups)
{// ^
You are passing stream by value to generateGroups() function which results in copy constructor call. Standard streams cannot be copied.
As for the second part of your question, you cannot expect PRNG to always return unique numbers, let alone when you limit the range with modulus. You'll need to write a bit more code which would check if the number you've got was already generated before, or in other words that some student has already been assigned.
The seed used by rand() won't repeat until 2^32 cycles or more on most implementations, but (seed>>xx)%n will repeat at least every n cycles and more frequently if n is not relatively prime to the numbers used by the linear congruential generator used by rand().
You could make an array of n bytes and use them to track if there's been a duplicate.