I'm working on a program and have debugged a lot of what I was doing wrong in it out. I have only one error and have read on stack and other forums about similar problems. But have tried to re-do it over and over with no positive results.
Error Shown in header code and it is:
binary'>>' no operator found which takes a right-hand operand of the type'overloaded-function'(or there is no acceptable conversion)
Month.h
#ifndef MONTH_H
#define MONTH_H
#include <iostream>
#include <string>
using namespace std;
class Month{
private:
static string name;
static int monthNumber;
public:
//Default Constructor
Month(){
setName("January");
setNumber(1);
}
//Input of month only constructor and assigning month number from input of name
Month(string n){
name = n;
setName(n);
if(name == "January" || name == "january"){
setNumber(1);
}
else if(name == "February" || name == "february"){
setNumber(2);
}
else if(name == "March" || name == "march"){
setNumber(3);
}
else if(name == "April" || name == "april"){
setNumber(4);
}
else if(name == "May" || name == "may"){
setNumber(5);
}
else if(name == "June" || name == "june"){
setNumber(6);
}
else if(name == "July" || name == "july"){
setNumber(7);
}
else if(name == "August" || name == "august"){
setNumber(8);
}
else if(name == "September" || name == "september"){
setNumber(9);
}
else if(name == "October" || name == "october"){
setNumber(10);
}
else if(name == "November" || name == "november"){
setNumber(11);
}
else if(name == "December" || name == "december"){
setNumber(12);
}
}
//Input of month number only and assigning month name to that number
Month(int n){
setNumber(n);
}
Month(int n, string m){
monthNumber = n;
name = m;
}
//Set the name of the month
void setName(string n){
name = n;
}
//Set the monthes number (and name for increment and decrement)
void setNumber(int n){
monthNumber = n;
switch(monthNumber){
case 1:
setName("January");
break;
case 2:
setName("February");
break;
case 3:
setName("March");
break;
case 4:
setName("April");
break;
case 5:
setName("May");
break;
case 6:
setName("June");
break;
case 7:
setName("July");
break;
case 8:
setName("August");
break;
case 9:
setName("September");
break;
case 10:
setName("October");
break;
case 11:
setName("November");
break;
case 12:
setName("December");
break;
}
}
//Return the name of the month
string getName(){
return name;
}
//Return the month number
int getNumber(){
return monthNumber;
}
//Overload the -- Operator
Month Month::operator--(int){
if(monthNumber == 1)
{
setNumber(12);
setName("December");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
Month Month::operator--(){
if(monthNumber == 1)
{
setNumber(12);
setName("December");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
//Overload the ++ operator
Month Month::operator++(int){
if(monthNumber == 12)
{
setNumber(1);
setName("January");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
Month Month::operator++(){
if(monthNumber == 12)
{
setNumber(1);
setName("January");
}
else {
monthNumber++;
setNumber(monthNumber);
}
}
//Overloading << and >>
friend ostream &operator<<(ostream &strm, const Month &obj){
strm << "# of Month : " << obj.name << " This Corresponds to the month : " << obj.monthNumber << endl;
return strm;
}
//Error here
//-------------------------------------------------------------------
//binary'>>' no operator found which takes a right-hand operand of
//the type'overloaded-function'(or there is no acceptable conversion)
//-------------------------------------------------------------------
friend istream &operator>>(istream &strm, Month &obj) {
strm >> obj.setNumber >> obj.setName;
return strm;
}
};
#endif
source.cpp
#include "Month.h"
#include <cstdlib>
#include <iostream>
using namespace std;
int main(){
Month coolio, first(1), second("June");
coolio++;
second--;
++first;
cout << "Enter the month number: " << endl;
cin >> coolio;
cout << coolio;
cout << second;
cout << first;
return 0;
}
You cannot read data from an input stream, and combine that with a method call. You need to read the data into a temporary int and a temporary string, and then use these int and string to call the setters, like this:
friend istream &operator>>(istream &strm, Month &obj) {
int number;
string name;
strm >> number >> name;
obj.setNumber(number);
obj.setName(name);
return strm;
}
Moreover, since >> is declared a friend, you can read directly into obj's member variables.
Here are some suggestions on how to simplify your program (so the rest of us don't have to wade through hundreds of lines of code):
Assign To Members directly
You don't need to call setName within the setNumber method.
Access the name variable directly.
One Text Case, One compare
Your code will fail for the case jUNe.
You could convert your month name to all lower case or all upper case before you compare. This reduces your if-else ladder by half.
Search the web for "c++ transform toupper".
Remove Month Compares
There's a fancy technique for mapping month names to numbers, but we'll not use that. You can use an array instead. Let the array index represent the month number:
static const char month_number_to_name[13] =
{
"Nothing",
"january", "february", "march", "april", "may", "june",
"july", "august", "september", "october", "november", "december",
};
// ...
std::cout << "The name of month 10 is: "
<< month_number_to_name[10]
<< "\n";
Save Month Name or Number
There is no need to save both the month name and number. With the translation array above you can convert between name and number.
I recommend keeping the month number variable. If you need the name, using the month number to get the name, the process the name.
Small size, small quantity of defects
There is much research in the programming industry that states the longer a program is, the high probability it will have more defects than a shorter one. Just consider the typing alone. More letters typed increases the chance for a typo.
Use data structures to your advantage to reduce your program size.
Related
My problem is I don't know how to get anything to output from here. I want to print the postfix result so far using printResult().. how can I do this? I am not sure how to cout the result I am getting inside my inToPost() function which should be the result of converting to postfix. Thanks.
#include <iostream>
#include <fstream>
#include <stack>
#include <string>
using namespace std;
class Expression{
public:
string inToPost();
string convertThis; // Expression that we want converted
Expression(string input, int direction); //constructor
bool isOperator(char character);
bool isOperand(char character);
int isHigherWeight(char character);
bool isHigherPrecedence(char op1, char op2);
string printResult();
private:
string infix;
string postfix;
string prefix;
};
//Constructor function
Expression::Expression(string input, int direction){
switch (direction){
case 1: infix = input;
case 2: postfix = input;
case 3: prefix = input;
}
}
//Operator Function checks to see if character is a legal symbol
bool Expression::isOperator(char character){
if((character == '*')||(character == '+')||(character == '-')||(character == '/'))
return true;
else
return false;
}
//Operand Function checks to see if character is a legal character
bool Expression::isOperand(char character){
if(character >= 'a' && character <= 'z')
return true;
if(character >= 'A' && character <= 'Z')
return true;
if(character >= '0' && character <= '9')
return true;
else
return false;
}
//Function determines the weight of Operator.
int Expression::isHigherWeight(char character){
int weight = 0; // or -1?
switch(character){
case '+':
case '-':
weight = 1;
case '*':
case '/':
weight = 2;
}
return weight;
}
//Function that compares weights of two different Operators.
bool Expression::isHigherPrecedence(char oper1, char oper2){
int op1Weight = isHigherWeight(oper1);
int op2Weight = isHigherWeight(oper2);
// If operators have equal precedence, return true
// return false
return op1Weight > op2Weight ? true: false;{
}
}
string Expression::inToPost(){
stack<char> Stack;
string postfix = ""; // Initialize postfix as empty string.
for(int i = 0;i< convertThis.length();i++){ //go through array of string convertThis
if (convertThis[i] == '('){ //1-Read the left parenthesis and push it onto the stack
Stack.push(convertThis[i]);
}
else if(isOperand(convertThis[i])){ //2-else if( the next input is a number or letter)
cout << convertThis[i]; //3-Read the operand and write it to the output
}
else if(isOperator(convertThis[i])){ //4-else if the next input is operator
cout << Stack.top();
Stack.pop(); //5-Print the top operation and pop it
}
//6-
while(!Stack.empty() && Stack.top() != '(' && isHigherPrecedence(Stack.top(),convertThis[i])){
Stack.push(convertThis[i]); //7- Read the next input symbol, and push this symbol onto the stack
}
// 8- Read and discard the next input symbol(which should be a right parenthesis).
if (convertThis[i] == ')'){
i+1;
// 9- Print the top operation and pop it; Keep printing and popping until
while (!Stack.top() == '('){
cout << Stack.top();
Stack.pop();
}
}
Stack.pop(); //10- Finally, pop the left parenthesis.
while(!Stack.empty()){
cout << Stack.top();
}
return postfix;
}
}
string Expression::printResult(){
return postfix;
}
int main(){
string convertThis;
int choice;
cout << "|-----Here is my conversion menu-----|" << endl;
cout << "|----What are you converting to?-----|" << endl << endl;
cout << "1- Infix to postfix" << endl;
cout << "2- Infix to prefix" << endl;
cout << "3- postfix to infix?" << endl;
cout << "4- prefix to infix?" << endl;
//cin >> choice;
//cin.ignore();
cout << "Now enter the expression you want to convert ";
getline(cin,convertThis);
//Expression printResult;
//cout << printResult.printResult();
}
Your question is far too complicated to be asking "How do I send output to the screen?" You have 10 functions in a class...a class that you never used in main. Half the functions are empty...Start smaller. Start with a class that has a private string variable, a constructor that takes a string and a single public function to display that string.
It will look something like this...
#include <string>
#include <iostream>
class MyClass{
public:
MyClass(std::string str) : m_string(str){}
void PrintString() { std::cout << m_string << std::endl; }
private:
std::string m_string;
};
int main(int argc, char * argv[]){
std::string inputString("This is my test string.");
MyClass myClass(inputString); // create an instance of your class
myClass.PrintString(); // Print the variable within your class
return 0;
}
Once you have that working add a second input to the constructor for your 4 options. There are many ways to do this. Then one by one add the remaining functions and test them.
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
Can someone explain to me what I'm doing wrong with the syntax below? My textbook doesn't have any examples of user-defined string functions and I can't figure out what I should be doing. Thanks in advance!
#include <iostream>
#include <cmath>
#include <cstdlib>
#include <string>
string dayOfWeek(int day);
using namespace std;
int main()
{
cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
cin >> day;
cout << "The name of the day of the week is: " dayOfWeek(day) << endl;
}
string dayOfWeek(int day)
{
if (day == 0)
return "SUNDAY";
else if (day == 1)
return "MONDAY";
else if (day == 2)
return "TUESDAY";
else if (day == 3)
return "WEDNESDAY";
else if (day == 4)
return "THURSDAY";
else if (day == 5)
return "FRIDAY";
else if (day == 6)
return "SATURDAY";
}
#include <string>
#include <iostream>
std::string dayOfWeek(int day)
{
if (day == 0)
return "SUNDAY";
else if (day == 1)
return "MONDAY";
else if (day == 2)
return "TUESDAY";
else if (day == 3)
return "WEDNESDAY";
else if (day == 4)
return "THURSDAY";
else if (day == 5)
return "FRIDAY";
else if (day == 6)
return "SATURDAY";
return "Invalid input!"; // May be you should guarantee a return value.
}
int main() {
std::cout << dayOfWeek(5) << std::endl;
}
should work as expected.
The crux of the problem is here:
string dayOfWeek(int day);
using namespace std;
The using is after code that depends on it, so the compiler goes looking for string and can't find it. It doesn't go looking for std::string because it hasn't been told to yet.
You could move using up a few lines, but for the many reasons covered in the answers to Why is "using namespace std" considered bad practice? and a few not covered, you're probably better off not putting
using namespace std;
in your code at all. Prefix the std:: explicitly and you can avoid a litany of nasty surprises.
I also recommend following #πάνταῥεῖ example with where the function was placed. Forward declaring and then declaring gives you two places to have to change code and one more place to have a bug. Declaring the function ahead where it will be used mean you only ever have to change one declaration.
Putting it all together with a few other small tweaks:
#include <string>
#include <iostream>
std::string dayOfWeek(int day)
{
switch (day) // for stuff like this, I like a switch. I find it looks nicer.
{
case 0:
return "SUNDAY";
case 1:
return "MONDAY";
case 2:
return "TUESDAY";
case 3:
return "WEDNESDAY";
case 4:
return "THURSDAY";
case 5:
return "FRIDAY";
case 6:
return "SATURDAY";
default:
return "No such day"; // functions must always return something.
// in this case what will cout print if you
// don't return a string? Don't know?
// Don't feel bad. Neither do I.
// Welcome to Undefined Behaviour
}
}
int main()
{
int day; //this was missing
std::cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
std::cin >> day;
std::cout << "The name of the day of the week is: " << dayOfWeek(day) << std::endl;
}
There's one other trick you can use to get rid of the if or switch entirely
#include <string>
#include <iostream>
// define an array of days of the week to print. const means dayOfWeek cannot be changed
const std::string dayOfWeek[] =
{
"SUNDAY",
"MONDAY",
"TUESDAY",
"WEDNESDAY",
"THURSDAY",
"FRIDAY",
"SATURDAY"
};
int main()
{
unsigned int day;
//Note unsigned int. Negative numbers are now disallowed
std::cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
// keep looping until user provides a good number
while (!(std::cin >> day) // user MUST input a number
|| day > 6) // number is a usable number
{
std::cin.clear(); // clean up bad input
std::cout << "Please enter a day of week (0 for Sunday, 1 for Monday, etc): ";
}
// since we know day is a usable (0..6) number we can read the day out of the array
std::cout << "The name of the day of the week is: " << dayOfWeek[day] << std::endl;
}
First post ever on this site so spare my life , please.
I'm trying to do a little encryption and decryption program imitating the Enigma cipher/machine from the WW2 (enough history lessons)
So I'm trying to input a number and a letter like so : 1h 2e 3l 4l 5o ;
Because I don't use a cycle I need to write for every variable that I'm adding the number , but what do I do if I have less letters than variables?The only way I can think of is using a cycle which checks if the input is a letter or not.That's why the current code I've written only can be used for specific amount of numbers and letters...
#include <iostream>
#include <limits>
using namespace std;
int main()
{
int opt;
cout<<"Enter 1 for encryption and 2 for decryption. "<<endl;
cin>>opt;
if(opt == 1)
{
int setting1,setting2,setting3,setting4;
char a,b,c,d;
cout<<"_________________________________________________"<<endl;
cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
a+=setting1;
b+=setting2;
c+=setting3;
d+=setting4;
cout<<(char)a<<" "<<(char)b<<" "<<(char)c<<" "<<(char)d<<endl;
}
if(opt == 2)
{
int setting1,setting2,setting3,setting4;
char a,b,c,d;
cout<<"_________________________________________________"<<endl;
cin>>setting1>>a>>setting2>>b>>setting3>>c>>setting4>>d;
a-=setting1;
b-=setting2;
c-=setting3;
d-=setting4;
cout<<(char)a<<(char)b<<(char)c<<(char)d<<endl;
}
if(opt !=1 && opt !=2)cout<<"ERROR!"<<endl;
std::cout << "Press ENTER to continue..."<<endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(),'\n');
return 0;
}
Also I was told that the last 2 lines would prevent the .exec from closing after it's done doing it's thing.
I recommend inputting your data in loops (cycles). But before that is accomplished, I suggest using a structure (or class) with an overloaded stream extraction operator.
struct Number_Letter
{
int number;
char letter;
friend std::istream& operator>>(std::istream& inp, Number_Letter& nl);
};
std::istream& operator>>(std::istream& inp, Number_Letter& nl)
{
inp >> nl.number;
if (inp)
{
inp >> nl.letter;
if (!isalpha(nl.letter))
{
// Error recovery for not reading a letter
}
}
else
{
// Error recovery for failing to read number.
}
return inp;
}
Your input loop would be something like:
Number_Letter nl;
while (std::cin >> nl)
{
// process the data
}
For cryptography, you may want to keep the data as a string:
std::string message;
getline(cin, message);
for (unsigned int i = 0; i < message.length(); i += 2)
{
if (!isdigit(message[i]))
{
cerr << "Invalid message type at position " << i << endl;
break;
}
if (i + 1 > message.length())
{
cerr << "Missing letter at end of message.\n";
break;
}
if (!isalpha(message[i+1]))
{
cerr << "Invalid message type at position " << i << endl;
break;
}
}
It sounds like you're trying to check for an unknown sequence of character/integers and need a loop to do the check?
int opt;
cout<<"Enter 1 for encryption and 2 for decryption. "<<endl;
cin>>opt;
if(opt != 1 && opt != 2)
{
cout << "Error" << endl;
return -1;
}
int integer;
char character;
char again;
do
{
cout<<"_________________________________________________"<<endl;
cin>>integer>>character;
if(opt == 1) {
character+=integer;
} else if(opt == 2) {
character-=integer;
}
cout << character <<endl;
cout << "Again (Y)?: ";
cin>>again;
}while(again == 'Y' || again == 'y');
std::cout << "Press ENTER to continue..."<<endl;
std::cin.ignore( std::numeric_limits<std::streamsize>::max(),'\n');
return 0;
Hi I am working on a program that should display the latter of two dates, it needs to accept two Date structures and return the latter of them. Latter being 04/31/2014 is latter then 04/30/2014. Here is my code and I do not understand why I am getting a long weird number... Thanks for helping.
#include <iostream>
#include <iomanip>
using namespace std;
struct Date
{
int day;
int month;
int year;
};
int main()
{
void laterDate(Date, Date);
Date one;
Date two;
Date later;
cout << "Enter a Date starting with the day, then month, then year:\n";
cin >> one.day;
cin >> one.month;
cin >> one.year;
cout << "\n\nEnter another date in the same fashion as above:\n";
cin >> two.day;
cin >> two.month;
cin >> two.year;
cout << "\n\nThank you, I will now tell you which date is later then the other!" << endl;
laterDate(one, two);
system("pause");
return 0;
}
void laterDate(Date o,Date t)
{
Date later;
if (o.year >= t.year)
if (o.month >= t.month)
if (o.day > t.day)
{
later.day= o.day;
later.month = o.month;
later.year = o.year;
}
else
{
later.day = t.day;
later.month = t.month;
later.year = t.year;
}
cout << later.day << "/" << later.month << "/" << later.year << endl;
}
OUTPUT
Enter a Date starting with the day, then month, then year:
04
30
2014
Enter another date in the same fashion as above:
04
31
2014
Thank you, I will now tell you which date is later then the other!
-858993460/-858993460/-858993460
Press any key to continue . . .
END OUTPUT
You should break out the logic of comparing the dates from the code which displays the results. The standard idiom for comparing objects that can be totally ordered (such as dates) is to overload operator<.
// the intent of this function is to return true if lhs precedes rhs,
// and return false otherwise (rhs precedes lhs, or they are equal)
bool operator<(Date const& lhs, Date const& rhs)
{
// first test the year.
// if the years differ, there is no need to test the month or the day
if (lhs.year < rhs.year) return true;
if (lhs.year > rhs.year) return false;
// years are equal, test the month
if (lhs.month < rhs.month) return true;
if (lhs.month > rhs.month) return false;
// months are equal, test the day
return lhs.day < rhs.day;
}
Then your function can be easily written like this:
void laterDate(Date const& lhs, Date const& rhs)
{
Date const& later = (lhs < rhs) ? rhs : lhs;
cout << later.day << "/" << later.month << "/" << later.year << endl;
}
if (o.year > t.year ||
(o.year >= t.year && o.month > t.month) ||
(o.year >= t.year && o.month >= t.month &&
o.day > t.day))
{
later.day= o.day;
later.month = o.month;
later.year = o.year;
}
else
{
later.day = t.day;
later.month = t.month;
later.year = t.year;
}
in this way , else will always be called , in your implementation it is only called when the two first condition where true, resulting in the display of random bits
I think I'd structure things a little differently. First, I'd make outputting a Date a friend function of the Date class and next, I'd overload the > operator for comparing Date class instances.
struct Date
{
int day;
int month;
int year;
friend std::ostream &operator<<(std::ostream& out, const Date &d) {
return out << d.day << "/" << d.month << "/" << d.year;
}
bool operator>(const Date &t) const;
};
The implementation of the > operator would look like this:
bool Date::operator>(const Date &t) const
{
if (year > t.year) return true;
if (year < t.year) return false;
if (month > t.month) return true;
if (month < t.month) return false;
return day > t.day;
}
And then your main routine would be this:
int main()
{
Date one;
Date two;
std::cout << "Enter a Date starting with the day, then month, then year:\n";
std::cin >> one.day >> one.month >> one.year;
std::cout << "\n\nEnter another date in the same fashion as above:\n";
std::cin >> two.day >> two.month >> two.year;
std::cout << "\n\nThank you: " << (one > two ? one : two)
<< " is the later date\n";
}
Note, too, that one can chain the input operator parts as shown here. In fact, I'd be inclined to declare an input operator operator>> and promote the Date struct to a full-fledged class.
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