I am currently studying c++ but I fell behind a little bit, so I apologize if my question is obvious.
I have to create a program that asks for a student's name, GPA, Year of admission, and get a random 5 digit number generated for that person. The number of students will not exceed 42.
My program compiled (somehow) and I am able to get the error for invalid menu selection, however, whenever I give a valid selection (currently 1) nothing happens.
Maybe I am missing something, this is why I need help.
Here is my code.
#include <iostream>
#include <stdlib.h>
#include <time.h>
using namespace std;
//print all the menu options
void print_menu()
{
cout<<"\nRCNJ Registrar Menu:"<<"\n"
<<"\n"
<<"[1] Add a student"<<"\n"
<<"[2] Display all students"<<"\n"
<<"[3] Display by year"<<"\n"
<<"[4] Display statistics"<<"\n"
<<"[5] Quit"<<"\n";
}
//get and return the student's name
void get_name(string& student_name) //call student_name after that.
{
cout<<"Please enter the sudent's name: ";
cin >> student_name;
cout<<"\n";
}
//validate and return gpa
double get_gpa()
{
double student_gpa = 0;
cout<<"Please enter the GPA: ";
cin >>student_gpa;
cout<<"\n";
while (student_gpa > 4 || student_gpa < 0)
{
cout<<"Please enter a valid GPA for the student (0.00 - 4.00): ";
cin >> student_gpa;
cout<<"\n";
}
return student_gpa;
}
//validateand return year
int get_year()
{
int student_year = 0;
cout<<"Please enter the year: ";
cin >> student_year;
cout<<"\n";
while (student_year >2016 || student_year <1972)
{
cout<<"Please enter a valid year (min 1972, max 2016): ";
cin >> student_year;
cout<<"\n";
}
return student_year;
}
//generate the student's R#
int generate_number()
{
int r_number;
srand (time(NULL));
r_number = rand() % 89999 + 10000;
return r_number;
}
//save info. Include get_name, get_gpa, get_year
void input_new_student()
{
string student_name;
double student_gpa;
int student_year;
int r_number;
int s_name, s_gpa, s_year, r_num;
get_name(student_name);
get_gpa();
get_year();
generate_number();
}
//display all students in the proper format
void print_all()
{
}
//get a year as selection and print all students that are the same year
void print_by_year()
{
}
//display statistics based on entered students
void print_statistics()
{
}
//validate and return the menu option selected by the user.
//it should call print_menu defined earlier
int get_selection(int menu_choice)
{
menu_choice = 0;
cout<<"\n"
<<"Selection: ";
cin >> menu_choice;
cout<<"\n";
while (menu_choice > 5 || menu_choice< 1)
{
cout<<" Menu choice is invalid. Please re-enter (1 - 5): ";
cin>> menu_choice;
cout<<"\n";
}
return menu_choice;
}
int main()
{
string student_name;
double student_gpa;
int student_year;
int r_number;
int menu_choice;
int s_name=0;
int s_gpa=0;
int s_year=0;
int r_num=0;
string nameArray[42];
s_name++;
double gpaArray[42];
s_gpa++;
int yearArray[42];
s_year++;
int ramapoArray[42];
r_num++;
print_menu();
get_selection(menu_choice);
switch (menu_choice)
{
case 1:
input_new_student();
nameArray[s_name] = student_name;
gpaArray[s_gpa] = student_gpa;
yearArray[s_year] = student_year;
ramapoArray[r_num] = r_number;
break;
}
return 0;
}
I dont have permission to comment, hence adding it here.
In you main(),
get_selection(menu_choice);
switch (menu_choice)
You return menu_choice, but there is none to take the value, you end you using garbage value as it is uninitialized.
So two ways you can do it, either by passing the address/reference of menu_choice or by return value. try either of these it should work, though I have not gone through the rest of your program.
As suggested by others, try a debugger e.g. gdb?
Related
asking desire number to become the for loop(how many employee if input is 4 then 4 loop if 3 3 loops), salary formula not working, if else statement for string name to not accept number and vice versa integer to not accept letters. another one of my problem is how can I name the loop for example the question is name hours and rate then the cout should do 1. name hours rate, 2.name hours rate 3.name hours rate... the code is working.. just need some imporvements.
#include <iostream>
#include <cstdlib>
using namespace std;
void displayRules()
{
cout<<"====================="<<endl;
cout<<" EMPLOYEE-SALARY "<<endl;
cout<<"====================="<<endl;
cout<<" "<<endl;
}
int main()
{
char ans;
do
{
system("cls");
displayRules();
struct Employee
{
string name;
double hours;
double rate;
double salary;
Employee *next;
Employee *prev;
};
Employee *head;
head=NULL;
Employee *newEmployee;
Employee *EmpPointer;
Employee *nextEmpPointer;
Employee *prevEmpPointer;
string inpname;
int inpN;
double inphours;
double inprate;
double salary;
salary = (inprate*inphours);
for(int ctr=0; ctr<3; ctr++)
{
cout<<endl;
cout<<"Enter Name: \t\t";
cin>> inpname;
cout<<"Enter # Hours Worked: \t";
cin>> inphours;
if (inphours<0)
{
cout << "Invalid Input! Program Stopped. ";
return 0;
}
cout<<"Enter Rate per Hour: \t";
cin>> inprate;
if (inprate<0)
{
cout << "Invalid Input! Program Stopped. ";
return 0;
}
newEmployee = new Employee;
newEmployee->name=inpname;
newEmployee->hours=inphours;
newEmployee->rate=inprate;
newEmployee->next=NULL;
if (head==NULL)
head=newEmployee;
else
{
EmpPointer=head;
while (EmpPointer->next)
EmpPointer=EmpPointer->next;
EmpPointer->next=newEmployee;
}
}
cout<<endl;
Employee *displayPointer;
displayPointer=head;
system("cls");
cout<<"------------------------------------------------------------"<<endl;
cout<<" =Summary of PAYROLL= "<<endl;
cout<<"------------------------------------------------------------"<<endl;\
cout<<"Employee Name\t"<<"# Hours Worked\t"<<"Rate/Hour\t"<<"Salary\t"<<endl;
while (displayPointer)
{
cout<<displayPointer->name<<"\t\t";
cout<<displayPointer->hours<<"\t\t";
cout<<displayPointer->rate<<"\t\t";
cout<<displayPointer->salary<<endl;
displayPointer=displayPointer->next;
}
cout<<"------------------------------------------------------------"<<endl;
cout<<endl;
cout << "Would you like to run the program again? (Y/N) ";
cin>>ans;
}
while (ans == 'y' or ans == 'Y');
return 0;
}
Note: The salary wasn't being calculated so I fix that.
I broke your code into small functions in which each function only does one thing and one thing only (Single Responsibility Principle).
Also, I introduce function templates that allows you to reuse a function when you provide the type.
Finally, the code is missing a clean up of pointers to prevent memory leaks. Each time you use the keyword new to obtain a pointer to memory, you need later to check if the pointer contains null and if doesn't then use the keyword delete to free that memory, else you end with memory leaks in your code. Therefore, I leave you with the task to write the function that should iterate your employee list and free the memory to prevent memory leaks.
I hope this is useful.
#include <iostream>
#include <cstdlib>
using namespace std;
struct Employee {
string name;
double hours;
double rate;
double salary;
Employee *next;
Employee *prev;
};
void displayRules() {
cout<<"====================="<<endl;
cout<<" EMPLOYEE-SALARY "<<endl;
cout<<"====================="<<endl;
cout<<" "<<endl;
}
// Here we create a function template to make this code more reusable
template <typename T>
T consoleInput(const std::string& prompt) {
T value;
std::cout << prompt;
std::cin >> value;
return value;
}
// Lets create our own assert to exit the app.
void assertGreaterEqualThanZero(const double value, const std::string& prompt){
if (value < 0) {
cout << prompt;
exit(1);
}
}
// Small functions that do one thing only makes coding easy to debug
Employee* createEmployee(string name, int hours, int rate) {
Employee *newEmployee = new Employee;
newEmployee->name=name;
newEmployee->hours=hours;
newEmployee->rate=rate;
newEmployee->salary = (rate * hours);
newEmployee->next=NULL;
// You need to set and maintain ->prev
// if you are thinking on using a double linked list
// else remove it from the structure since is unused.
return newEmployee;
}
// This is a helper function to add new employees to a list
Employee* addToEmployeeList(Employee* list, Employee* newEmployee){
if (list==NULL) {
list = newEmployee;
} else {
Employee *EmpPointer = list;
while (EmpPointer->next)
EmpPointer=EmpPointer->next;
EmpPointer->next=newEmployee;
}
return list;
}
// The only purpose of this function is to print the list provided
void printEmployeList(Employee* employeeList){
Employee *currentEmployee = employeeList;
system("cls");
cout<<"------------------------------------------------------------"<<endl;
cout<<" =Summary of PAYROLL= "<<endl;
cout<<"------------------------------------------------------------"<<endl;
while (currentEmployee){
cout<<"Employee Name\t"<<"# Hours Worked\t"<<"Rate/Hour\t"<<"Salary\t"<<endl;
cout<<currentEmployee->name<<"\t\t";
cout<<currentEmployee->hours<<"\t\t";
cout<<currentEmployee->rate<<"\t\t";
cout<<currentEmployee->salary<<endl;
cout<<"------------------------------------------------------------"<<endl;
currentEmployee=currentEmployee->next;
}
}
// I leave you with this piece that is missing.
// TODO: create function that delete each employee in the list,
// then deletes the list in order to prevent memory leaks
int main() {
char ans;
do {
system("cls");
displayRules();
Employee *employeeList;
employeeList=NULL;
for(int ctr=0; ctr<3; ++ctr) {
// Lets declare and instantiate when we need it.
string name = consoleInput<string>("Enter Name: \t\t");
// No need to use inp (as inphours) in front of your variables
// It makes it harder to read. Just put hours as a name.
double hours = consoleInput<double>("Enter # Hours Worked: \t");
assertGreaterEqualThanZero(hours, "Invalid Input! Program Stopped.");
double rate = consoleInput<double>("Enter Rate per Hour: \t");
assertGreaterEqualThanZero(rate, "Invalid Input! Program Stopped. ");
Employee *newEmployee = createEmployee(name, hours, rate);
employeeList = addToEmployeeList(employeeList, newEmployee);
}
cout << endl;
printEmployeList(employeeList);
cout << "Would you like to run the program again? (Y/N) ";
cin>>ans;
} while (ans == 'y' or ans == 'Y');
return 0;
}
the question asks me to repeat this program until users enter X. what should I do to loop this program? should I use while?
question: repeat the program until the user enter X for package code
#include <iostream>
using namespace std;
int main(){
int price_package;
char package_code;
int num;
int no_of_adults;
int no_of_childs;
cout<<"Enter package code: ";
cin>>package_code;
if(package_code=='A'){
cout<<"Enter number of adults: ";
cin>>no_of_adults;
cout<<"Enter number of childs: ";
cin>>no_of_childs;
price_package= ((40*no_of_adults)+(21*no_of_childs));
cout<<"price package: RM"<<price_package<<endl;
}
else if(package_code=='B'){
cout<<"Enter number of adults: ";
cin>>no_of_adults;
cout<<"Enter number of childs: ";
cin>>no_of_childs;
price_package=((23*no_of_adults)+(14*no_of_childs));
cout<<"price package: RM"<<price_package<<endl;
}
else if(package_code=='C'){
cout<<"Enter number of adults: ";
cin>>no_of_adults;
cout<<"Enter number of childs: ";
cin>>no_of_childs;
price_package=((38*no_of_adults)+(18*no_of_childs));
cout<<"price package: RM"<<price_package<<endl;
}
else{
cout<<"ERROR";
}
}
You could use a while loop or a do while loop. Both of which would look like the following:
// import and variables here
do{
// logic to loop
} while(package_code!='X')
Or
// imports and variables
//declare package_code with some value other than 'X'
while(package_code!='X'){
//loop logic
}
Try this
#include <iostream>
using namespace std;
void Output(int no_of_adults, int no_of_childs, int price_package)
{
cout<<"Enter number of adults: ";
cin>>no_of_adults;
cout<<"Enter number of childs: ";
cin>>no_of_childs;
cout<<"price package: RM"<<price_package<<endl;
}
int main()
{
int price_package;
char package_code;
int num;
int no_of_adults;
int no_of_childs;
while (1)
{
cout<<"Enter package code: ";
cin>>package_code;
if(package_code=='A')
{
price_package= ((40*no_of_adults)+(21*no_of_childs));
Output(no_of_adults, no_of_childs, price_package);
}
else if(package_code=='B')
{
price_package=((23*no_of_adults)+(14*no_of_childs));
Output(no_of_adults, no_of_childs, price_package);
}
else if(package_code=='X')
{
break;
}
else
{
cout<<"ERROR"<<endl;
}
}
}
I am instructed that I have to reject any decimal and I need to re enter the number again.I tried this code but still it just goes to the whole process before acknowledging the error. Try the program and judge me :D here's my code:
#include<iostream>
#include<cstdlib>
#include<cmath>
#include<limits>
using namespace std;
int getInt()
{
int m=0;
while (!(cin >> m))
{
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
cout << "Please input a proper 'whole' number: " ;
}
return (m);
}
int main()
{
double x;
int q,w,e,choice;
cout<<"Welcome! This program will sort out the integers you will input!\nPlease input number of integers: ";
cin>>q;
cout<<endl<<endl;
int* inc= new int[q];
int* dec= new int[q];
for(int p=1;p<=q;++p)
{
w=p;
e=p;
cout<<"Input integer number "<<p<<": ";
x =getInt();
while(e>0 && inc[e-1]>x)
{
inc[e]=inc[e-1];
e--;
}
while(w>0 && dec[w-1]<x)
{
dec[w]=dec[w-1];
w--;
}
inc[e]=x;
dec[w]=x;
}
cout<<endl;
cout<<"What order do you prefer? Input 1 for increasing and 2 if decreasing.\nChoice: ";
cin>>choice;
while(choice<1 || choice>2)
{
cout<<"Please input a correct choice! Try again!\nChoice: ";
cin>>choice;
}
if(choice==1)
{
for(int i=0;i<q;++i)
cout<<inc[i]<<"\t";
cout<<endl;
}
else
{
for(int i=1;i<=q;++i)
cout<<dec[i]<<"\t";
cout<<endl;
}
system("PAUSE");
}
hoping for your help :)
You can try using modulo.
Just an idea, hope it helps.
bool flag = false;
While (flag == false){
cin>>number;
if ((number % 1) != 0){
flag = false;
}
else{
flag = true;
}
cin.clear();
}
Try making a copy of the number you want to test and casting it to an int and then back to a double, and then check for equality. If they are equal, you have an int, if they are not, you have a decimal:
#include <iostream>
using namespace std;
int main()
{
double a = 5;
double c = 5.5;
double b = a;
bool test1 = (double)((int)b) == a; //true!
b = c;
bool test2 = (double)((int)b) == c; //false!
cout << test1 << endl;
cout << test2 << endl;
return 0;
}
Wrote this answer a long time ago, it is very hacky and will not work on all inputs. Use std::stoi and check if it throws as the comment suggests instead.
Why is the following code not giving results and how to get results?
Whenever I run the code, it first asks for the names of the players of two teams playing the match, then it shows the menu from which if we select any one of the option it again asks for the batsman name which is not according to the program designed. My research on the code and the problem is that I think buffer memory is full but I don't know how to free it, any help would be beneficial. Thank you
#include<iostream>
#include<string.h>
#include<conio.h>
using namespace std;
class scorecard{
char batname[11][20];
int runscored[11];
char situation[11][10];
char mode[11][15];
char bowlername[11][20];
float oversplayed[11];
int maiden[11];
int runsgiven[11];
int wicketstaken[11];
public:
void updatebatsman(void);
void updatebowler(void);
void displaybat(void);
void displaybowl(void);
void menu(void);
scorecard()
{for(int n=0;n<12;n++)
{
runscored[n]={0};
oversplayed[n]={0};
maiden[n]={0};
runsgiven[n]={0};
wicketstaken[n]={0};
}
}
};
int main()
{
int jb=0;
scorecard s1;
int kb;
s1.menu();
do
{
cout<< "Enter the option"<<endl;
cout<<"(1) Display batting score"<<endl<<"(2) Display Bowling score"<<endl<<"(3) Update batting score"<<endl;
cout<<"(4) Update Bowling score"<<endl;
cin >>kb;
switch(kb)
{
case 1 : s1.displaybat();
break;
case 2 :s1.displaybowl();break;
case 3:s1.updatebatsman();break;
case 4:s1.updatebowler();break;
default:cout<<"Wrong choice";
}
}while (jb<1);
}
void scorecard::updatebowler(void)
{char bowlname[20];
int str,k,option,overnumbers,maidenumb,uprun,upwicket;
cout<<"Enter Bowler name:";
cin.getline(bowlname,20);
for( k=0;k<11;k++)
{str= strcmp(bowlername[k],bowlname);
if (str== 0)
{
cout<<"Menu for Bowler information update "<<endl;
cout<<"(1) Update Number of overs"<<endl<<"(2) Update maiden overs"<<endl<<"(3) Update runs given"<<endl;
cout<<"(4) Update wickets taken"<<endl;
cin >> option;
switch(option)
{
case 1:{cout<<"Enter Numbers of overs to be updated:";
cin >>overnumbers;
cout<<endl;
oversplayed[k]+=overnumbers;
break;
}
case 2:{cout <<"Enter the number of maiden overs to be updated:";
cin>>maidenumb;
cout<<endl;
maiden[k]+=maidenumb;
break;
}
case 3:{cout <<"Enter the number of runs to be added:";
cin>>uprun;
cout<<endl;
runsgiven[k]+=uprun;
break;
}
case 4: {cout<<"Enter number of wickets to be updated:";
cin >>upwicket;
cout<<endl;
wicketstaken[k]+=upwicket;
}
default:cout<<"wroung choice";
}
break;
}
}
if (str!=0)
cout <<"You entered wrong player."<<endl;
}
void scorecard::updatebatsman(void)
{char batsmaname[20];
int str,k;
cout<<"Enter Batsman name:";
cin.getline(batsmaname,20);
for( k=0;k<11;k++)
{str= strcmp(batname[k],batsmaname);
if (str== 0)
{
cout<<"enter runs scored:";
cin>>runscored[k];
cout<<endl<<"enter weather out or not out:";
cin>>situation[k];
cout<<endl<<"enter mode(if batsman out) by which batsman was out:";
cin>>mode[k];
break;
}
}
if (str!=0)
cout <<"You entered wrong player."<<endl;
}
void scorecard::displaybat(void)
{
cout << "Batsman name"<<'t'<<"Runs scored"<<'t'<<"situation"<<'t'<<"mode"<<endl;
for(int j=0;j++;j<12)
{
cout<<batname[j]<<'t'<<runscored[j]<<'t'<<situation[j]<<'t'<<mode[j]<<endl;
}
}
void scorecard::displaybowl(void)
{
cout << "Bowler name"<<'t'<<"overs played"<<'t'<<"maiden overs"<<'t'<<"wicket taken"<<'t'<<"Runs given"<<endl;
cout<<endl;
for(int j=0;j++;j<12)
{
cout<<bowlername[j]<<'t'<<oversplayed[j]<<'t'<<maiden[j]<<'t'<<wicketstaken[j]<<'t'<<runsgiven[j]<<endl;
}
}
void scorecard::menu(void)
{
cout<<"Enter the name of players of batting team"<<endl;
for (int k=0;k<11;k++)
{
cout <<"Enter name of player "<<k+1<<":";
cin>>batname[k];
}
cout <<"Enter the name of players of bowling team"<<endl;
for (int n=0;n<11;n++)
{
cout <<"Enter name of player "<<n+1<<":";
cin>>bowlername[n];
}
}
This is very wrong:
for(int j=0;j++;j<12)
It should be:
for(int j=0; j < 11; j++)
You are also missing a break in your case 4 statement for the options:
case 4: {cout<<"Enter number of wickets to be updated:";
cin >>upwicket;
cout<<endl;
wicketstaken[k]+=upwicket;
break;
}
default:cout<<"wroung choice";
Without the break you will see also the output wrong choice when the user selects option 4.
class flight //main class flight which the user uses to book tickets
{
int booking_id;
int pnr,p_age;
char p_name[25],d_a_name[25],a_a_name[25],gender,departing_date[10],arrival_date[10],b_id;
long double price;
public:
flight()
{
static int id=0;
booking_id=id++;
}
void modfunction(int n);
};
void flight::modfunction(int n) //function for entering new values when the user has chosen to modify
{
getchar();
cout<<"Enter the passenger's name :";
gets(p_name);
cout<<"Enter the passenger age :";
cin>>p_age;
getchar();
cout<<"Enter the passenger's gender :";
cin>>gender;
getchar();
cout<<"Enter the departing date(dd-mm-yyyy) :";
gets(departing_date);
cout<<"Do you want to book return ticket with a 10% discount?(y/n) :";
cin>>return_ticket_input;
if(return_ticket_input=='y')
{
cout<<"Enter the arrival date :";
gets(arrival_date);
}
cout<<"Choose the airline.\n\n";
flights(departing_date,return_ticket_input,arrival_date);
cout<<"\n\nEnter the desired flight number :";
cin>>selected_fno;
}
void modify_ticket()//function for modifying a ticket
{
int n;
system("clear");
cout<<"Enter the booking id for modification ";
cin>>n;
flight f;
fstream fp("flight.dat",ios::binary);
ifstream ifile("flight.dat",ios::binary);
int found=0;
int count_variable = 0;
while(ifile.read((char*)&f,sizeof(f)))
{
if(n==f.retbid())
{
f.output();
f.modfunction(n);
// int s=sizeof(f) * (count_variable + 1);
fp.seekp(ifile.tellg());
fp.write((char*)&f,sizeof(f));
found = 1;
f.output();
getchar();
}
count_variable++;
}
ifile.close();
fp.close();
if(found==0)
{
cout<<"Passenger not founed!";
}
cout<<"Press any key to continue.";
getch();
}
So this is the minimal version of my problem.
The class named flight. a function called modfuction which is used to input data from the user. and another function called modify ticket used by the user to modify the record details.
The problem is even though the user enters the booking id(n) and it outputs the record, when the user tries to update it(modify) it stays the same!
please help me as this is a part of my school project!
thanks in advance!
Instead of fstream fp("flight.dat",ios::binary); write:
fstream fp("flight.dat",ios::binary|ios::in|ios::out);
P.S.: Encountered Same Problem A minute ago..