0

I have this assignment on Structs for my Computer Science class. The problem is that on the function

void input (Time & time);

When I try to call the function, the error

FATAL ERROR: Input failure

is printed. Here is what the function is supposed to do:

void input( Time & time ); input’s job is to input a time that looks like Wednesday 7:05 PM and set the Time arg accordingly (in this case, to {3, true, 7, 5}). If the input fails or is invalid, complain and die. (Your ok function can do some, not all, of this checking.) You’ll (try to) input 5 things: day, hour, colon, minute, ampm. If any input leaves cin in an error state, complain and die. If the day doesn’t exactly match one of the days in your const global array of day names, complain and die. (Let’s make life a little easier for us and a little harder on the user by saying that the day name must have exactly the case we’re expecting: first letter upper case, remaining letters lower case. That way we don’t have to bother with case conversion.) If the hour isn’t in the legal range, complain and die. If the char we input after the hour isn’t a colon, complain and die. If the minute isn’t in the legal range, complain and die. If the AM/PM designation doesn’t exactly match "AM" or "PM" (case sensitive), complain and die. If we survive, our job is to set time. For instance, wednesday 7:05 PM complains and dies (bad day name (case error)) For instance, Wednesday x:00 PM complains and dies (bad hour) For instance, Wednesday 0:00 PM complains and dies (bad hour) For instance, Wednesday 7;05 PM complains and dies (bad colon) For instance, Wednesday 7 PM complains and dies (bad colon) For instance, Wednesday 7:x PM complains and dies (bad minute) For instance, Wednesday 7:60 PM complains and dies (bad minute) For instance, Wednesday 7:05 pm complains and die (bad AMPM (case error)) You don’t have to generate distinct error message for all these possibilities, you can just say something like Fatal error: bogus time input if there’s any problem with the input.

If anyone can tell me what I'm doing wrong I would really appreciate it. I removed all of the portions that are irrelevant to the issue.

#include<iostream>
#include<string>
#include<sstream>
#include<cctype>

using namespace std;

//Structs
struct Address {
    unsigned number;
    string street;
    string suffix;
    string city;
    string state;
    unsigned zip;
};

struct Time {
    unsigned day;
    bool pm;
    unsigned hour;
    unsigned minute;
};

//Prototypes
void show(const Address & address);
void show(const Address address[], unsigned elements, unsigned desiredZip);
void show(const Address address[], unsigned addressElements, const unsigned desiredZip[], unsigned desiredZipElements);
void show(const Time & time);
bool ok(const Time & time);
int compare(const Time & time0, const Time & time1);
bool die(const string & msg);
int nameAsDay(const string &day); //My own function
void input(Time & time);

const string days[7] = { "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" };

int main() {

    Address addList[7] = { a1, a2, a3, a4, a5, a6, a7 };
    unsigned zipList[2] = { 91324, 91325 };

    Time t1 = { 0, false, 12, 1 };
    Time t2 = { 0, 0, 12, 0 };
    Time t3 = { 4, true, 5, 30 };
    Time t4 = { 1, false, 11, 60 };
    Time t5 = { 7, 1, 9, 1 };
    Time t6 = { 0, 0, 12, 0 };
    Time t7;

    show(a1);
    show(addList, 7, 91329);
    show(addList, 7, zipList, 2);
    show(t2);
    cout << ok(t2) << endl;
    cout << compare(t1, t2) << endl;
    input(t3);
    show(t3);


    system("pause");
    return 0;
}

//Displays time and day
void show(const Time & time) {
    cout << days[time.day] << " " << time.hour << ":";
    if (time.minute == 0)
        cout << "00";
    else if (time.minute < 10)
        cout << "0" << time.minute;
    else
        cout << time.minute;
    if (time.pm == 0)
        cout << " AM" << endl;
    else
        cout << " PM" << endl;
}

//Determines if the data for struct Time is valid
bool ok(const Time & time) {
    if ((time.day < 0) || (time.day > 6))
        return false;
    if ((time.hour < 1) || (time.hour > 12))
        return false;
    if ((time.minute < 0) || (time.minute > 59))
        return false;
    return true;
}

//Compares two times to see which comes first
int compare(const Time & time0, const Time & time1) {
    //Check that time is correctly entered
    if ((!ok(time0)) || (!ok(time1)))
        die("Unable to interpret input");

    if (time0.day < time1.day)
        return -1;
    else if ((time1.day == time0.day) && (time1.pm == true) && (time0.pm == false))
        return -1;
    else if ((time1.day == time0.day) && (time1.pm == time0.pm) && (time0.hour < time1.hour))
        return -1;
    else if ((time1.day == time0.day) && (time1.pm == time0.pm) && (time1.hour == time0.hour) && (time0.minute < time1.minute))
        return -1;
    else if ((time1.day == time0.day) && (time1.pm == time0.pm) && (time1.hour == time0.hour) && (time1.minute == time0.minute))
        return 0;
    else
        return 1;
}

//Die function, exits program
bool die(const string & msg) {
    cout << endl << "FATAL ERROR: " << msg << endl;
    return -1;
}

string convertDayToString(const Time &time) {
    const string day[7] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };

    return days[time.day];
}

//My own function - changes day to an element #
int nameAsDay(const string &day) {
    if (day == "Sunday")
        return 0;
    else if (day == "Monday")
        return 1;
    else if (day == "Tuesday")
        return 2;
    else if (day == "Wednesday")
        return 3;
    else if (day == "Thursday")
        return 4;
    else if (day == "Friday")
        return 5;
    else if (day == "Saturday")
        return 6;
    else 
        return 100; //Input failure
}

//Set the time argument and discern errors
void input(Time & time) {
    string userInput;
    unsigned found, hour, minute;

    if (nameAsDay(userInput) == 100) 
        die("Input failure.");
    else 
        time.day = nameAsDay(userInput);

    cin >> userInput;
    found = userInput.find(":");

    if (found == 2) {
        if (isdigit(userInput[0]) && isdigit(userInput[1])) {
            stringstream(userInput.substr(0, 2)) >> hour;
            if ((hour > 0) && (hour < 13))
                time.hour = hour;
            else
                die("Hour out of range.");
        }
        else
            die("Invalid hour input.");
        if (isdigit(userInput[3]) && isdigit(userInput[4])) {
            stringstream(userInput.substr(3, 1)) >> minute;
            if ((minute >= 0) && (minute <= 59))
                time.minute = minute;
            else
                die("Minute out of range.");
        }
        else
            die("Invalid minute input.");
    }
    else
        die("Invalid time input.");

    cin >> userInput;
    if (userInput == "AM")
    time.pm = false;
else if (userInput == "PM")
    time.pm = true;
else
    die("Invalid AM/PM input.");
 }
2
  • 1
    string userInput;...if (nameAsDay(userInput) == 100).userInput is uninitialized. Commented Sep 17, 2018 at 22:10
  • @JohnnyMopp Not strictly true, it's initialised to the empty string. Commented Sep 17, 2018 at 22:12

1 Answer 1

1

You should read your input before you start testing it. This

cin >> userInput;
if (nameAsDay(userInput) == 100) 
    die("Input failure.");
else 
    time.day = nameAsDay(userInput);

instead of this

if (nameAsDay(userInput) == 100) 
    die("Input failure.");
else 
    time.day = nameAsDay(userInput);
cin >> userInput;

Although looking more closely I wonder if the code isn't meant to be this

cin >> userInput;
if (nameAsDay(userInput) == 100) 
    die("Input failure.");
else 
    time.day = nameAsDay(userInput);
cin >> userInput;

Either way you need to read some input before you call nameAsDay.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.