Program gives me wrong output, can someone take a look? [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
So here's the question:
An office starts its work on 8:00:00 and employees may leave on 17:00:00.
Write an OOP program that gets the time that an employee enters and exits.
If an employee comes later than 8:10:00, program should say that the employee has delayed and if sooner than that, it should say that the employee was on time. If one exits later than 17:30:00, the program should say that the employee has stayed an overtime and if sooner than that, the program should say that the employee has exited on time .
So here's the code:
#include <iostream>
using namespace std;
class wTime
{
public:
void get_entime(int, int, int);
void get_extime(int, int, int);
bool calc_en();
bool calc_ex();
void show_result();
private:
int h1, m1, s1;
int h2, m2, s2;
};
void wTime::get_entime(int x=8,int y=0, int z=0)
{
x = h1;
y = m1;
z = s1;
cout << "Enter the entry time in 24 hour format (hh mm ss): " << endl;
cin >> x >> y >> z;
}
void wTime::get_extime(int a=17, int b=0, int c=0)
{
a = h2;
b = m2;
c = s2;
cout << "Enter the exit time in 24 hour format: (hh mm ss) : " << endl;
cin >> a >> b >> c;
}
bool wTime::calc_en()
{
if (h1 > 8)
return true;//takhir dashte;
if (h1 == 8 && m1 > 10 )
return true;//takhir dashte;
if (h1 < 8)
return false;//on time boode;
if (h1 == 8 && m1 < 9)
return false;//on time boode;
}
bool wTime::calc_ex()
{
if (h2 > 17)
return true;//ezafe kari dashte;
if (h2 >= 17 && m2 >= 30)
return true;//ezafe kari nadashte
if (h2 == 17 && m2 < 30)
return false;
}
void wTime::show_result()
{
if (calc_en() == true)
cout << "Employee has delayed." << endl;
if (calc_en() == false)
cout << "Employee was on time" << endl;
if (calc_ex() == true)
cout << "Employee has stayed an overtime" << endl;
if (calc_ex() == false)
cout << "Employee has exited on time." << endl;
}
int main()
{
wTime em;
em.get_entime();
em.calc_en();
em.get_extime();
em.calc_ex();
em.show_result();
cin.ignore();
cin.get();
return 0;
}
The problem is that, for every hh mm ss that I enter it just returns
Employee has delayed.
Employee has exited on time.
What's wrong?

When you take the user input via cin, you're putting it in local variables (specifically the function parameters) which get destroyed immediately afterwards. You're not actually storing them for the subsequent calculations.
You probably want to do something like this:
void wTime::get_entime()
{
cout << "Enter the entry time in 24 hour format (hh mm ss): " << endl;
cin >> h1 >> m1 >> s1;
}
(Do the equivalent for get_extime() too). That will store the values in the member variables so that they can be used in the calculation methods.

bool wTime::calc_en()
{
if (h1 > 8)
return true;//takhir dashte;
if (h1 == 8 && m1 > 10 )
return true;//takhir dashte;
if (h1 < 8)
return false;//on time boode;
if (h1 == 8 && m1 < 9)
return false;//on time boode;
}
you should put in a default return value
for example 8:10 or 8:09 don't get evaluated (the same problem exists in wTime::calc_ex)
and of course the previously mentioned input problems

Related

Debugger has correct output but normal execution does not

I'm having this strange issue where my code does exactly what I want it to when I run it through my debugger, but it doesn't work when I run it normally. What's stranger is that I am not getting a runtime error either. This is where the issue might be, but I'm not 100% sure on this:
void calcMostMissed (double *ptr, int totalContestants, int arrSize)
{
//output header
cout << endl << "MOST MISSED QUESTIONS" << endl;
//check how many times a question is missed and its percentage, then output it if it's above 60%
double curQuest = *ptr;
int freq = 0;
int j = 0;
double percentMissed;
for (int i = 0; i <= arrSize; i++) //loop through the missed questions array
{
if (*(ptr + i) > 0) //if pointer is pointing at a question number (extra space in array is set to 0)...
{
if (*(ptr + i) == curQuest) //then check how often it occurs in the array
freq++;
}
else //if the pointer is not pointing at a question number anymore...
{
//calculate percent missed and output it if its 60% or greater
percentMissed = (static_cast<double>(freq) / totalContestants) * 100;
if (percentMissed >= 60)
{
cout << static_cast<int>(curQuest) << "\t" << fixed << setprecision(2) << percentMissed << "%" << endl;
}
// check if the question's percentage missed has already been calculated and evaluated
j++;
curQuest = *(ptr + j);
int r = 0;
while (r < j)
{
if (*(ptr + r) == curQuest)
{
if (j < arrSize - 1)
{
j++;
curQuest = *(ptr + j);
}
}
r++;
}
if (!(j == arrSize - 1 && r == arrSize - 1))
{
i = 0;
}
freq = 0;
}
//if the current question variable has been through all missed question, then leave loop
if (curQuest < 1)
{
break;
}
}
}
What this function is supposed to do overall is find the percent missed on all missed questions and output only the ones that are above 60% inclusive.
This is what my debugger outputs (and what I want it to look like):
Enter name of answer key file: batch7a.txt
Enter name of contestant's answers file: allWrongContestants.txt
oo12345678 - 0.00
1 2 3
C A B
A B C
0012387654 - 0.00
1 2 3
C A B
A B C
0012364213 - 0.00
1 2 3
C A B
A B C
Mean: 0.00
Median: 0.00
Mode: 0.00
MOST MISSED QUESTIONS
1 100.00%
2 100.00%
3 100.00%
This is what a normal execution ouputs:
Enter name of answer key file: batch7a.txt
Enter name of contestant's answers file: allWrongContestants.txt
oo12345678 - 0.00
1 2 3
C A B
A B C
0012387654 - 0.00
1 2 3
C A B
A B C
0012364213 - 0.00
1 2 3
C A B
A B C
Mean: 0.00
Median: 0.00
Mode: 0.00
MOST MISSED QUESTIONS
Process returned 0 (0x0) execution time : 14.442 s
Press any key to continue.
My debugger runs through all the way to the end of my program just fine, but for some reason the normal execution is still flawed. Any suggestions are welcome and I'll clarify anything that I may have forgotten to mention.
If it helps, I am using Code::Blocks as my IDE
Some other info about my code: there are 3 questions and all contestants scored a 0% on the test, meaning all questions have the incorrect answers.
Output: The numbers are the contestant's ID, next to that is their score, the list of numbers underneath is the question number they got wrong, underneath that are the contestant's answers, and under that are the correct answers.
This is the function that calls the calcMostMissed function:
void statReport (double *ptr, int totalScores, double *mmqPtr, int arrSize)
{
//calculate mean of scores
double mean = calcMean(ptr, totalScores);
//calculate median of scores
double median = calcMedian(ptr, totalScores);
//calculate mode of scores
double *mode = calcMode(ptr, totalScores);
//output to console the data
cout << "Mean: " << fixed << setprecision(2) << mean << endl;
cout << "Median: " << median << endl;
cout << "Mode: ";
sort(mode, mode + totalScores);
int j = 0;
for (int i = 0; i < totalScores; i++)
{
if (*(mode + i) != -1)
{
if (j == 0)
{
cout << *(mode + i);
}
else
{
cout << ", " << *(mode + i);
}
j++;
}
}
cout << endl;
//call calcMissedQuestions function
calcMostMissed(mmqPtr, totalScores, arrSize);
//delete pointers
delete[] mode;
mode = nullptr;
delete[] mmqPtr;
mmqPtr = nullptr;
}
And this is the main function:
int main()
{
string answerKeyName;
string contestantAnswerName;
ifstream answerKeyFile;
ifstream contestantAnswerFile;
//ask for file names
cout << "Enter name of answer key file: ";
cin >> answerKeyName;
cout << "Enter name of contestant's answers file: ";
cin >> contestantAnswerName;
//check if files can be opened properly
answerKeyFile.open(answerKeyName, ios::binary);
contestantAnswerFile.open(contestantAnswerName, ios::binary);
if(!answerKeyFile)
{
cout << "Answer key file could not be opened" << endl;
exit(EXIT_FAILURE);
}
if (!contestantAnswerFile)
{
cout << "Contestant's answers file could not be opened" << endl;
exit(EXIT_FAILURE);
}
//find how many contestant's there are
int i = 0;
string temp;
while (contestantAnswerFile.good())
{
getline(contestantAnswerFile, temp);
if (temp != "")
{
i++;
}
}
contestantAnswerFile.clear();
contestantAnswerFile.seekg(0, ios::beg);
//create contestant's score array
double *scorePtr = new double[i];
//create pointer for all missed questions
double *mmqPtr = nullptr;
int arrSize;
//compare the contestant's answers to the answer key, then fill array with score
double score;
for (int c = 0; c < i; c++)
{
score = compareAnswers (contestantAnswerFile, answerKeyFile, mmqPtr, i, arrSize);
*(scorePtr + c) = score;
}
//create the statistics report
statReport(scorePtr, i, mmqPtr, arrSize);
//delete dynamically allocated array
delete[] scorePtr;
scorePtr = nullptr;
//close files
answerKeyFile.close();
contestantAnswerFile.close();
return 0;
}
Below is where I think the issue resides, however I still cannot properly compile it because other functions and input files are not provided, probably rightly so in order not to further congest the question:
double *mmqPtr = nullptr; is defined in main(), then it's passed to the statReport() function without having been associated with any object.
Afterward it acts as first parameter for function calcMostMissed() and gets dereferenced inside it, but is still a nullptr, so this produces undefined behaviour.
There is also the issue of an out-of-bounds index inside a loop, as pointed at in the comments.

SIGSTP error in lead game problem of codechef. TLG problem

`
#include<bits/stdc++.h>
#include <iostream>
#include<vector>
using namespace std;
int main() {
// your code goes here
int t;
cin >> t;
vector<int>v1, v2;
v1.push_back(0);
v2.push_back(0);
while (t--)
{
int a, b;
cin >> a >> b;
if (a > b)
v1.push_back(a - b);
else
v2.push_back(b - a);
}
int m1, m2;
if (v1.size() > 1)
m1 = *max_element(v1.begin(), v1.end());
else
m1 = 0;
if (v2.size() > 1)
m2 = *max_element(v2.begin(), v2.end());
else
m2 = 0;
if (m1 > m2)
cout << "1" << " " << m1;
else
cout << "2" << " " << m2;
}
`
this is lead game question in codechef but I am getting SIGSTP error while running code. I am not getting how to overcome this. I have spend my a plenty of time. Can someone help me to getting rid of this problem.I am new in the competitive programming. Please suggest me some resources or lectures on youtube to do better.
Thanks in Advance...
Submitting this code didn't got me SIGSTP but I got Wrong Answer verdict. This is due to the fact that you are not checking the cumulative scores of the players but directly comparing the current scores and pushing them in the vectors accordingly. You can maintain two variables to store the cumulative scores of the players and then check that which player has the current lead. Try the following solution:
int main()
{
int rounds;
cin >> rounds ;
int lead = 0 ;
int player = 0;
int cs1 = 0 , cs2 = 0 ;
while(rounds--){
int p1 , p2 ;
cin >> p1 >> p2 ;
cs1+=p1;
cs2+=p2;
if(cs1 > cs2 && lead < (cs1 - cs2) ){
lead = cs1 - cs2 ;
player = 1;
}
else if(cs2 > cs1 && lead < (cs2 - cs1))
{
lead = cs2 - cs1 ;
player = 2;
}
}
cout << player << " " << lead << endl;
return 0;
}
int main() {
// your code goes here
int n;
cin>>n;
int max=0,player=1;
int cs1=0,cs2=0;
for(int i=0;i<n;i++)
{
int si,ti;
cin>>si>>ti;
cs1=cs1+si;
cs2=cs2+ti;
if(abs(cs1-cs2)>max)
{
max=abs(cs1-cs2);
if(cs1>cs2)
player=1;
else
player=2;
}
}
cout<<player<<" "<<max<<endl;
return 0;
}
Ive provided an alternate approach to the TLG problem. When you get the input compute the cumulative scores then and there itself and later assign the difference to the player who has higher cumulative score.Hope this helps!

c++: for not working as intended [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
My question is when I run the code,and call for the list,so I press 3,nothing happens and it just skips over the code in for(). Why does this occur and how can I fix it?
Simple code would be welcome.I am now to this.
The first two int before the main checks if the student is qualified for the school,or not.i tested those and they are working great.
The struct describes a student.He/She has a name(nev),marks (bacmagy,bacrom,bacmat,bacvalasz).A boolean value(langexam) is present,to represent is the student has a language exam or not.
bsiker is true,if the formula in calculateBac turns out to be true.
atmente is true,if bsiker and langexam are both true.
The listing would spit out the name,bsiker and atmente.
#include <iostream>
using namespace std;
int atmegye(bool elso, bool masodik){
if (elso && masodik)
return true;
else
return false;
}
int calculateBac(double magy, double mat, double rom, double val){
double osszeg = magy + mat + rom + val;
osszeg = osszeg / 4;
if (magy < 5 || mat < 5 || rom < 5 || val < 5 || osszeg < 6)
return false;
else
return true;
}
int main(){
struct diak{
char nev[32];
bool langexam, atmente, bsiker;
double bacmagy, bacrom, bacmat, bacvalasz, bac;
};
diak v[150];
bool cap = false;
int opcio;
int j, n = 0;
int i = 0;
do{
cout << "\n Welcome. \n 1-new studient \n 2-Change a studient's details \n 3-List \n 4-Exit \n";
cin >> opcio;
switch (opcio){
case 4:{
return 0;
}
case 1:{
cout << "Please give the name of the student: ";
cin >> v[i].nev;
cout << "Hungarian mark: ";
cin >> v[i].bacmagy;
cout << "Romanian mark: ";
cin >> v[i].bacrom;
cout << "Maths mark: ";
cin >> v[i].bacmat;
cout << "Optional mark: ";
cin >> v[i].bacvalasz;
cout << " Do you have a language exam? Please respond with 1 or 0: ";
cin >> v[i].langexam;
v[i].bsiker = calculateBac(v[i].bacmagy, v[i].bacrom, v[i].bacmat, v[i].bacvalasz);
v[i].atmente = atmegye(v[i].bsiker, v[i].langexam);
i = i + 1;
i = n;
cout << n;
break;
}
case 3: {
for(i = 0; i < n; i++)
cout << v[i].nev << " " << v[i].bsiker << " " << endl;
break;
}
}
}while (opcio != 5);
}
This line is wrong:
i = n;
it should be:
n = i;
Your code is just undoing the i = i + 1; line that precedes it.
n is initialized as 0 and never set to any other value. Therefore your for loop is not supposed to run any iteration
The problem is in the for loop's conditional. You initialized the value of n to 0, and that value never seems to change. The variable i is also initialized to 0 inside the for loop. When the user chooses option 3, the for loop conditional ( 0 < 0) is evaluated which is false, so the for loop is skipped every time. So, to fix this problem, you need to update the value of n somewhere in your code, or you need to change your conditional statement. Hope this helps!
I know this probably won't help for your assignment, but here's a (one of many) way to handle this is a more c++-like manner, and without using OOP.
The standard library and the c++ type system give us plenty of useful tools to avoid writing bugs in the first place (that's really nice!), and find the one that are left at compile-time (saves a ton of time!). That's what the biggest difference between c and c++ is, and it is a very important one.
#include <iostream>
#include <vector>
#include <string>
#include <string.h>
// fixed-size record to save in data file, for example.
struct diak{
char nev[32];
bool langexam, atmente, bsiker;
double bacmagy, bacrom, bacmat, bacvalasz, bac;
};
void atmegye(diak& student)
{
student.atmente = student.bsiker && student.langexam;
}
void calculateBac(diak& student) // computes grades average, checks if passed.
{
double osszeg = student.bacmagy + student.bacmat + student.bacrom + student.bacvalasz;
student.bac = osszeg / 4.0;
student.bsiker = student.bacmagy >= 5
&& student.bacrom >= 5
&& student.bacmat >= 5
&& student.bacvalasz >= 5
&& student.bac >= 5; // this last test unnecessary, but rules are rules.
}
void AddNewStudent(std::ostream& os, std::istream& is, std::vector<diak>& students)
{
diak new_student;
std::string temp;
while(temp.empty())
{
os << "Student name: ";
is >> temp; // using a temp buffer avoids out of bounds errors
}
if (temp.length() >= sizeof(new_student.nev))
temp.resize(sizeof(new_student.nev) - 1);
strcpy(new_student.nev, temp.c_str());
// input values below SHOULD be validated for range (0-100)
// or whatever makes sense for your school.
os << "Hungarian mark: "; is >> new_student.bacmagy;
os << "Romanian mark: "; is >> new_student.bacrom;
os << "Maths mark: "; is >> new_student.bacmat;
os << "Optional mark: "; is >> new_student.bacvalasz;
// example validation. Validating user input is the worst!
// above ^^^ grades ^^^ can use a common function for validation.
for(;;)
{
os << " Do you have a language exam? Please respond with 1 or 0:";
is >> temp;
if (temp == "0")
{
new_student.langexam = false;
break;
}
if (temp == "1")
{
new_student.langexam = true;
break;
}
// not a valid entry, try again!
}
calculateBac(new_student);
atmegye(new_student);
students.push_back(new_student);
}
void EditSudent(std::ostream& os, std::istream& is, std::vector<diak>& students)
{
// query which student then edit using streams 'os' and 'is' for i/o.
}
// could also be used to write to file...
void PrintStudents(std::ostream& os, const std::vector<diak>& students)
{
// maybe by printing a student number you could reuse this
// function from EditStudent()...
//
// At the same time, it is only 2 lines of code. You decide.
for(size_t i = 0; i < students.size(); i++)
os << students[i].nev << " " << students[i].bsiker << "\n";
os.flush();
}
int main()
{
std::vector<diak> students; // could also be an std::list<>
while(true) // 1 less line of code than do {...} while, and easier to read.
{
int opcio = 0;
std::cout << "\n Welcome."
"\n 1-new studient"
"\n 2-Change a studient's details"
"\n 3-List "
"\n 4-Exit \n";
std::cin >> opcio;
switch (opcio)
{
case '1':
AddNewStudent(std::cout, std::cin, students);
break;
case 2:
EditSudent(std::cout, std::cin, students); // << queries student and edit that
break;
case 3:
PrintStudents(std::cout, students);
break;
case 4:
return 0;
}
}
}
Note how the tasks are very well delimited into their own function, this also helps finding bugs faster, as it makes the code easier to read and reason about (the famous divide and conquer strategy).
Having the students array (or list) as a single entity simplifies its management, no extra variable to keep up to date, etc...
In a more serious application, the input validation would be best done using a template, and would give the user an escape character so he could cancel adding the new student at any time.

C++ Find the middle value of any inputted data type using function templates?

I've run into a bit of snag with this it seemed simple enough at first but now I just can't seem to work it out, any help would be greatly appreciated.
So the question is: a user inputs three values of data type either, int, float, or char. The program then has to return the middle value.
Here is what i have so far:
The exercise requires that I use a function template and nothing like an array.
Header File:
#ifndef MIDTEMP_H
#define MIDTEMP_H
template <class T>
T doMiddle(T param, T param2, T param3)
{
if ((param<param2 && param>param3) || (param<param3 && param>param2) || (param == param2 == param3))
{
return param;
}
else if ((param2<param && param2>param3) || (param2<param3 && param2>param) || (param2 == param == param3))
{
return param2;
}
else if ((param3<param2 && param3>param) || (param3<param && param3>param2) || (param3 == param2 == param))
{
return param3;
}
else if (param == param2 && param < param3)
{
return param;
}
}
#endif
This now is the code which will test my header function:
#include<iostream>
#include "Middle.h"
using std::cin;
using std::cout;
using std::endl;
int main()
{
cout << "Please enter 3 integers. IF input is incorrect please input until correct." << endl;
cout << endl;
int a, b, c;
while (!(cin >> a >> b >> c))
{
cin.clear();
cin.ignore();
}
cout << "The Middle is: " << doMiddle(a, b, c) << endl;
cout << endl;
//=======================================================
cout << "Please enter 3 floating point values. IF input is incorrect please input until correct." << endl;
cout << endl;
float d, e, f;
while (!(cin >> d >> e >> f))
{
cin.clear();
cin.ignore();
}
cout << "The Middle is: " << doMiddle(d, e, f) << endl;
cout << endl;
//=======================================================
cout << "Please enter 3 characters. IF input is incorrect please input until correct." << endl;
cout << endl;
char g, h, j;
while (!(cin >> g >> h >> j))
{
cin.clear();
cin.ignore();
}
cout << "The Middle is: " << doMiddle(g, h, j) << endl;
cout<<endl;
return 0;
}
So it works decently but lets say I do this (from cmd):
Please enter 3 integers. IF input is incorrect please input until correct.
5
3.2
6
2
The Middle is: 2
Please enter 3 floating point values. IF input is incorrect please input until
9.0
9
9.0
The Middle is: -1.#IND
Please enter 3 characters. IF input is incorrect please input until correct.
r
r
r
The Middle is: r
why is it returning that -1.#IND value and is there some other way of doing this without those ridiculous if statements?
template<class T>
T doMiddle(T t1, T t2, T t3){
T arr[]={t1,t2,t3};
using std::begin; using std::end;
std::nth_element( begin(arr), begin(arr)+1, end(arr) );
return arr[1];
}
would do the trick. Why reinvent the wheel?
Your function prints -1.#IND because your template function does not return a value if all check fail(which occurs if all values are the same).
When all values inputed are the same, (param == param2 == param3) will always evaluate to false because param == param2 evaluates to a bool and a bool(true for example) is not equal to 9.0(from your example).
The template method then exits without returning and you get garbage out from the stack when you print.
Your check for equality should really be the first one like:
if ((param == param2) && (param2 == param3))
return param;
Then you go on checking for the middle value and don't forget to return something in a last else case.
Speaking of checking, your logic is flawed if only 2 values are equal. You should also be cautious about comparing float values directly since some near values might be represented as the same float value.

code falling through on an if statement [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 9 years ago.
Improve this question
When I add the second if to test for car size M to calculateTotalCarCharge then try to test the condition of c, I'm getting an answer for m (77.28 & 167.44) when I really want (68.73 & 148.92), its almost like the code is somehow falling through to the next condition
Test conditions
Type - Days - Amount
C - 3 - 68.73
M - 3 - 77.28
C - 7 - 148.92
M - 7 - 167.44
#include <iostream> //for I/O
#include <iomanip> //for formatting output
#include <cmath> //for math
using namespace std;
//prototypes
char validateCarChoice();
void displayProgramDescription();
int validateNumEntry(string prompt);
double calculateTotalCarCharge (char carSize, int daysRented);
//global constants
const char COMPACT = 'C';
const char MID = 'M';
const char FULL = 'F';
const char SUV = 'S';
const double COMPACT_DAILY_CHARGE = 22.91;
const double MID_DAILY_CHARGE = 25.76;
const double FULL_DAILY_CHARGE = 28.87;
const double SUV_DAILY_CHARGE = 98.88;
// --------------------------------------------------------------------------
// Description:
// Input parameter:
// Returns:
// ---------------------------------------------------------------------------
int main()
{
//local constants
const string ENTER_DAYS_RENTED = "Enter the number of days rented: ";
const string ENTER_MILES_DRIVEN = "Enter number of miles driven: ";
//local variables
char userCarTypeChosen;
char carSize;
int daysRented;
double milesDriven;
double carCharge;
//call function to display program description
displayProgramDescription();
//calls function to validate the car choice input by user
userCarTypeChosen = validateCarChoice();
//if car type chosen is suv (S) then only prompt will be to enter days
//rented, if not prompt both days rented and miles driven.
if (userCarTypeChosen == 'S')
{
daysRented = validateNumEntry(ENTER_DAYS_RENTED);
}
else
{
daysRented = validateNumEntry(ENTER_DAYS_RENTED);
milesDriven = validateNumEntry(ENTER_MILES_DRIVEN);
}
carCharge = calculateTotalCarCharge(carSize, daysRented);
//to be removed
cout << carCharge;
return 0;
}
// --------------------------------------------------------------------------
// Description: displayProgramDescription - displays program description
// Input parameter: N/A
// Returns: N/A
// ---------------------------------------------------------------------------
void displayProgramDescription()
{
//local constant
const string PROGRAM_DESCRIPTION = "This program will calculate a car rental"
" bill for Rent2U.";
//displays program description
cout << PROGRAM_DESCRIPTION << endl;
}
// --------------------------------------------------------------------------
// Description: validateCarChoice - displays menu of car options and daily cost.
// Then error checks that a valid choice was given
// Input parameter: N/A
// Returns: letter of car chosen
// ---------------------------------------------------------------------------
char validateCarChoice ()
{
//local constants
const string ENTER_CAR_LETTER = "Enter letter for car size rented: ";
const string ERROR_CAR_INPUT = "Re-enter letter for car size rented: ";
//local variable
char carSize;
//displays car size options
cout << "Car sizes:" << endl << endl;
cout << setw(5) << "C - Compact size at $ 22.91 per day" << endl;
cout << setw(5) << "M - Mid size at $ 25.76 per day" << endl;
cout << setw(5) << "F - Full size at $ 28.76 per day" << endl;
cout << setw(5) << "S - SUV at $ 98.88 per day" << endl << endl;
//prompt for user input
cout << ENTER_CAR_LETTER;
cin >> carSize;
carSize = toupper(carSize);
//validation of car type chosen
while (carSize !='C' && carSize !='M' && carSize !='F' && carSize !='S')
{
cout << ERROR_CAR_INPUT;
cin >> carSize;
carSize = toupper(carSize);
}
return carSize;
}
// --------------------------------------------------------------------------
// Description: validateNumEntry - validates that the user entry is at least 1
// Input parameter: prompt- prompts user to enter number
// Returns: the user inputed number
// ---------------------------------------------------------------------------
int validateNumEntry (string prompt)
{
//local constant
const string ERROR = "Error - entry must be at least 1.";
//local variable
double num;
cout << prompt;
cin >> num;
while (num < 1)
{
cout << ERROR << endl;
cout << prompt;
cin >> num;
}
return num;
}
// --------------------------------------------------------------------------
// Description:
// Input parameter:
// Returns:
// ---------------------------------------------------------------------------
double calculateTotalCarCharge (char carSize, int daysRented)
{
//local constant
const int WEEK = 7;
const double LOWER_WEEK_RATE = 6.5;
//local variable
double totalCarCharge;
int wholeWeek;
int extraDays;
if (carSize = 'C')
{
if (daysRented < WEEK)
{
totalCarCharge = (COMPACT_DAILY_CHARGE * daysRented);
}
else
{
wholeWeek = (daysRented / WEEK);
extraDays = (daysRented % WEEK);
totalCarCharge = ((wholeWeek * LOWER_WEEK_RATE *
COMPACT_DAILY_CHARGE) + (extraDays * COMPACT_DAILY_CHARGE));
}
}
//once i add this if condition, if I try and test C I get the calculations
//for M
if (carSize = 'M')
{
if (daysRented < WEEK)
{
totalCarCharge = (MID_DAILY_CHARGE * daysRented);
}
else
{
wholeWeek = (daysRented / WEEK);
extraDays = (daysRented % WEEK);
totalCarCharge = ((wholeWeek * LOWER_WEEK_RATE * MID_DAILY_CHARGE)
+ (extraDays * MID_DAILY_CHARGE));
}
}
return totalCarCharge;
}
For checking condition you have to use:
if (carSize == 'M')
and
if (carSize == 'C').
Because when you use the statement:
if (carSize = 'M') will just assign value carSize to 'M'
and will execute code inside the if statement.
This condition is same for if (carSize = 'C') too.
OR use switch statement:
switch (carSize)
{
case 'C':
if (daysRented < WEEK)
...
break;
case 'M':
// ...
}
As pointed out in the comments, you are assigning in your if statement in (carSize = 'C') and (carSize = 'M'). Out of interest, why not opt for a switch on the char here? It seems the branches are mutually exclusive, and you aren't mutating carSize in the branches? This might help avoid this kind issue in future:
switch (carSize)
{
case 'C':
if (daysRented < WEEK)
...
break;
case 'M':
// ...
}
Edit
There is a second bug in your code, in that you are assigning:
userCarTypeChosen = validateCarChoice();
But then you are passing the uninitialized variable carSize to the calculateTotalCarCharge function:
carCharge = calculateTotalCarCharge(carSize, daysRented);
You should change the assignment to carSize
carSize = validateCarChoice();
and then remove the userCarTypeChosen variable entirely.
In these comparisons to literals, a good idea can be to reverse the operands, which will throw a compiler error if you use single equal instead of double equal.
if (var == 'C') // compiles, runs correctly
if (var = 'C') // compiles, runs incorrectly, results in stackoverflow question
if ('C' == var) // compiles, runs correctly
if ('C' = var) // does not compile, fix this problem immediately