0

I am trying to write a program which calculates the cost of a call based on the time the call was made, the day of the week and length of call. It has to be all call-by-value functions and output a option to repeat the program.

My problem is when I enter a invalid input for time such as a:37, it outputs invalid input but continues to the day input instead of returning to time entry. I am a new programmer and have tried everything I can think of to fix it but it either gets stuck in a infinite loop of exits the entire program.

Thanks in advance for any help!

#include <iostream>
using namespace std;

bool validateUserInputTime(int,char,int);
bool validateUserInputDay(string);
bool validateUserInputCallLength(int);
double calculateTotalCost(int,int,string,int);

string days[]={"Mo" , "Tu" , "We" , "Th" , "Fr" , "Sa" , "Su"};
float cost,fcost;

int main()
{
int hour;
int min;
int time;
char colon;
char answer = 'y';
string day;
string s;
bool result;

while(answer =='y')
{
    cout<<"Enter the time the call starts in 24-hour rotation: "<<endl;
    cin>>hour>>colon>>min;


    result=validateUserInputTime(hour,colon,min);
    if(cin.fail())
    {
        cout << "Invalid time input."<<endl;
        cout<<"Please try again."<<endl<<endl<<endl;
        cin.clear();

    }

    day=validateUserInputDay(s);
    if(cin.good())
    {
        cout<<"Enter the first two letters of the day of the week:";
        cin>>day;
    }


    cout<<"Enter the length of the call in minutes:"<<endl;
    cin>>time;

    result=validateUserInputCallLength(time);

    if(result==0)
    {
        cout<<"Invalid minute Input."<<endl;
        cout<<"Please try again."<<endl<<endl<<endl;

        continue;
    }

    fcost= calculateTotalCost(hour,min,day,time);

    cout<<"Cost of the call: $" << fcost<<endl;
    cout<<"Do you want to repeat the program?";

    cin>>answer;


}

return 0;

}
bool validateUserInputTime(int hour1,char ch,int min1)
{
    if (cin.fail())
    {
        cout << "Invalid time input."<<endl;
        cout<<"Please try again."<<endl<<endl<<endl;
        cin.clear();
    }
    if(hour1 < 0)
    {
        return false;
    }

    if(min1 < 0)
    {
        return false;
    }
    if(ch!=':')
    {
        return false;
    }
    else
        return true;

}
bool validateUserInputDay(string s)
{
    int next=0;

    for(int i = 0; i < 7; i++)
    {
        if(days[i] == s){

        next=1;
    }
        if(cin.fail())
        {
            cout<<"Invalid day inpuT."<<endl;

            cin.clear();
        }    

}

    if(next==1)
    {
        return true;
    }
    else
    {
        return false;
    }
}

bool validateUserInputCallLength(int time2)
{

if(time2<0)
{
    return false;
}
else
{
    return true;
}

}
double calculateTotalCost(int hour3,int min3,string d,int time3)
{

if((d=="Sa")||(d=="Su"))

{

    cost=0.15*time3;

}

else

{

    if((hour3>=8)&&(min3<18))

    {

        cost=0.40*time3;

    }

    else

        cost=0.25*time3;

}

return cost;

}
Sam S.
  • 19
  • 4
  • 3
    you're not checking what `validateUserInputTime` is returning. You need to something like `if (result == false) { ... }` where the code in the braces is similar to what you sis after `validateUserInputCallLength` – Steve Lorimer May 11 '18 at 21:01
  • Your question is off-topic without a [mcve]. – Ulrich Eckhardt May 11 '18 at 21:02
  • I only comment this because it took me a moment to realize what 'colin' was. ':' is spelled colon. – Andrue May 11 '18 at 21:04
  • I must have accidentally erased the if statement, I just edited it, how should I correct my question to be on topic, and I apologize I will fix it to colon. – Sam S. May 11 '18 at 21:07
  • I suggest you read the line from the user instead, then analyze the line. e.g. using std::getline, then parse the string. that way you can have more control of what the user entered. – AndersK May 11 '18 at 21:18

2 Answers2

0

Try using a loop. The loop will stop the program from progressing until the result value is true.

result = false;
while (!result)
{
    cout<<"Enter the time the call starts in 24-hour rotation: "<<endl;
    cin>>hour>>colin>>min;
    result=validateUserInputTime(hour,colin,min);
}

You also forgot to put a false return statement on validateUserInputTime. Inputting non-digit characters might also crash the program, and cin.ignore happened to fix it.

if (cin.fail())
{
    cout << "Invalid time input."<<endl;
    cout<<"Please try again."<<endl<<endl<<endl;
    cin.clear();
    cin.ignore();
    return false;
}
0

If you want to parse what the user entered do something like this instead

std::string time;
std::getline(std::cin, time);

now check if there is a ':' auto pos = time.find(':'); if (pos != -1) {} then take out the hour part time.substr(0,pos) then the minute part time.substr(pos+1) then check if they are valid hour and minutes using e.g. stoi().

also it is better to do {} while () instead of while (answer == 'y') {...}

AndersK
  • 35,813
  • 6
  • 60
  • 86