http://www.stroustrup.com/Programming/PPP2code/std_lib_facilities.h
My version is spelt differently so adjust the code accordingly if copying and pasting.
Chapter 5 // Exercise 14
Read (day-of-the-week,value) pairs from the standard input. For example:
Tuesday 23 Friday 56 Tuesday -3 Thursday 99
Collect all the values for each day of the week in a vector<int>.Write out the values of the seven day-of-the-week vectors. Print out the sum of the values in each vector. Ignore illegal days of the week such as Funday, but accept common synonyms such as Mon and monday. Write out the number of rejected values.
#include "stdafx.h"
#include "std_lib_facilities_new_version.h"
using namespace std;
void getData();
int checkIllegalDotw();
void printVectors();
void printSum();
vector<int> values;
vector<string> dotw;
vector<string> acceptedDays = {
"Monday", "monday", "mon", "Mon",
"Tuesday", "tuesday", "tue", "Tue",
"Wednesday", "wednesday", "wed", "Wed",
"Thursday", "thursday", "thurs", "Thurs",
"Friday", "friday", "fri", "Fri",
"Saturday", "saturday", "sat", "Sat",
"Sunday", "sunday", "sun", "Sun" };
int g_rejectedValues = 0;
string g_inputDotw;
int g_inputValues;
int g_n = 0;
int main()
try
{
cout << "Please enter Day of The Week followed by value. Enter from Monday to Sunday: \n";
//get days of the week & values
getData();
//print out both vectors
printVectors();
//print sum & rejected values
printSum();
keep_window_open();
return 0;
}
catch (exception& e)
{
cerr << "Error: " << e.what() << '\n';
keep_window_open();
return 1;
}
//this gets input & checks if g_inputDotw is == to anything within acceptedDays
void getData()
{
while (dotw.size() < 7)
{
cout << "Day of The Week: ";
cin >> g_inputDotw;
g_n = checkIllegalDotw();
while (g_n == 0)
{
cout << "Sorry, that is not an accepted Day of The Week. Try again: \n" << endl;
++g_rejectedValues;
cin >> g_inputDotw;
g_n = checkIllegalDotw();
}
cout << "Value: ";
cin >> g_inputValues;
dotw.push_back(g_inputDotw);
values.push_back(g_inputValues);
}
cout << '\n';
}
//if n is equal to 0 then inputDotw made no matches to anything in acceptedDays
int checkIllegalDotw()
{
for (int i = 0; i < acceptedDays.size(); ++i)
{
if (g_inputDotw == acceptedDays[i])
{
++g_n;
}
}
return g_n;
}
void printVectors()
{
for (int x = 0; x < dotw.size(); ++x)
{
cout << dotw[x] << '\t' << values[x] << '\n';
}
}
void printSum()
{
int sum = 0;
for (int i = 0; i < values.size(); ++i)
{
sum += values[i];
}
cout << "The sum of the values is: " << sum << '\n';
cout << "Amount of Week days rejected: " << g_rejectedValues << '\n';
}
It was the omitting illegal days that got me stuck on this one however eventually I created a function which compares the input to each member of the vector that contains allowed days of the week. Basically if inputDotw makes a match to any of those numbers g_n increases making it no longer equal to 0. If it is equal to 0 you know that the input was wrong. I suppose I could've used a bool function for this instead but I still don't feel 100% confident using them yet.
Also, for anyone wondering about the g_ prefix on some variables, it's just to denote that it is a global variable and can therefore be accessed in any part of the code.
EDIT 18/03/2018
As part of exercise 11 in Chapter 7, you are told to revisit 2 programs from chapters 4 or 5. I chose this one as I didn't realise just how much not using bools was holding me back. Here is the new code for this exercise:
EDIT 18/03/2018
As part of exercise 11 in Chapter 7, you are told to revisit 2 programs from chapters 4 or 5. I chose this one as I didn't realise just how much not using bools was holding me back. Here is the new code for this exercise:
#include "stdafx.h" #include "std_lib_facilities.h" #include <windows.h> class ValuePair { private: //create a name value pair variable struct DayValue { int value; string day; }; public: //functions void getValues(); void printVectors(); //variables DayValue dayvalue; //holds int and string pair vector<DayValue> dayValueVector; //vector to store days and values created from struct vector<string> acceptedDays = { //list of days allowed "Monday", "monday", "mon", "Mon", "Tuesday", "tuesday", "tue", "Tue", "Wednesday", "wednesday", "wed", "Wed", "Thursday", "thursday", "thurs", "Thurs", "Friday", "friday", "fri", "Fri", "Saturday", "saturday", "sat", "Sat", "Sunday", "sunday", "sun", "Sun" }; int rejectedValues; string input; int values; }; //get values, checks for illegal input void ValuePair::getValues() { bool stop = false; //to stop loop bool allowedDay = false; cout << "Please enter a Day of the Week followed by a value. Press 'q' in day to stop.\n"; //while not 'q' keep getting entries while (!stop) { allowedDay = false; //reset bool for loop cout << ">Day: "; cin >> input; //if input is q, exit loop to main if (input == "q") { stop = true; return; } else { //check to see if day is allowed, if allowed set to true, if not ++ rejected value for (int i = 0; i < acceptedDays.size(); ++i) { if (input == acceptedDays[i]) { allowedDay = true; dayvalue.day = input; } } //get a value cout << ">Value: "; cin >> values; //if not a number, keep looping til number entered while (!cin) { ++rejectedValues; cin.clear(); //reset stream cin.ignore(10000, '\n'); //ignore everything entered till newline cout << "Not a number, try again > "; cin >> values; } //if day was valid pushback both values, if not ++rejected values and don't pushback if (allowedDay) { dayvalue.value = values; dayValueVector.push_back(dayvalue); //push values back into vector } else ++rejectedValues; } } } //print the valid values in vector as well as sum and rejected values void ValuePair::printVectors() { int value = 0; for (int i = 0; i < dayValueVector.size(); ++i) { cout << "Day: " << dayValueVector[i].day << " Value: " << dayValueVector[i].value << endl; value += dayValueVector[i].value; } cout << "\nSum of all Values: " << value << endl; cout << "Number of Rejected Values: " << rejectedValues << endl; } ValuePair dayAndValue; //start main program int main() { //get values and check them dayAndValue.getValues(); //print the vector and the sum of all values dayAndValue.printVectors(); //keep the the window open keep_window_open(); return 0; }
This now handles all errors. Also instead of the very confusing way I was checking for illegal input before, now I check the input against the allowed values and if it finds one, it sets a bool to true. Only when this bool is true will it pushback both values into the vector, if not it will still ask for a value but ignore them as per what is asked for.
EDIT 30/09/2019
What a mess these previous answers were. Here is the new code: https://github.com/l-paz91/principles-practice/blob/master/Chapter%205/Exercise14
It doesn't have fancy checking, i.e it expects numbers for number input (or it will throw a runtime error) but I have no idea what was going through my mind 3 years ago.
I did this one using bool function.
ReplyDeleteVery Easy and less complicated!
#include "../../std_lib_facilities.h"
int main()
try
{
vector day = { "Monday", "monday", "mon", "Mon",
"Tuesday", "tuesday", "tue", "Tue",
"Wednesday", "wednesday", "wed", "Wed",
"Thursday", "thursday", "thurs", "Thurs",
"Friday", "friday", "fri", "Fri",
"Saturday", "saturday", "sat", "Sat",
"Sunday", "sunday", "sun", "Sun" };
vector days;
vector day_number;
int sum = 0;
string day_name;
int day_num = 0;
int reject = 0;
cout << "Write your day name and day number. \n";
int d = 1;
while (d<=7)
{
cin >> day_name>> day_num;
bool ok = false;
for (int i = 0; i < day.size(); ++i)
{
if (day_name == day[i])
{
days.push_back(day_name);
day_number.push_back(day_num);
ok = true;
++d;
}
}
if (ok == false)
{
cout << "Invalid day name. Try Again!\n";
++reject;
}
}
for (int i = 0; i < day_number.size(); ++i)
sum = sum + day_number[i];
for (int i = 0; i < 7; ++i)
cout << '\n' << days[i] << '\t' << day_number[i] << '\n';
cout << "Total sum of number of days = " << sum << '\n';
cout << "Total rejected values: " << reject << '\n';
keep_window_open("~");
}
catch (exception& e)
{
cerr << "error: " << e.what() << '\n';
keep_window_open();
return 1;
}
catch (...) {
cerr << "Oops: unknown exception!\n";
keep_window_open();
return 2;
}
Blogspot omitted my comment:
ReplyDeletevector day = { "Monday", "monday", "mon", "Mon",
"Tuesday", "tuesday", "tue", "Tue",
"Wednesday", "wednesday", "wed", "Wed",
"Thursday", "thursday", "thurs", "Thurs",
"Friday", "friday", "fri", "Fri",
"Saturday", "saturday", "sat", "Sat",
"Sunday", "sunday", "sun", "Sun" };
vector days;
vector day_number;
It did it again....
ReplyDeleteWHY IS IT DELETING string between conical brackets?
vector "<" string ">" day = { "Monday", "monday", "mon", "Mon",
"Tuesday", "tuesday", "tue", "Tue",
"Wednesday", "wednesday", "wed", "Wed",
"Thursday", "thursday", "thurs", "Thurs",
"Friday", "friday", "fri", "Fri",
"Saturday", "saturday", "sat", "Sat",
"Sunday", "sunday", "sun", "Sun" };
vector "<" string ">" days;
vector "<" int">" day_number;
It's ok, the comment sections on most places don't really support code, I understand what your trying to do though :).
DeleteThis is awesome, much less code, you should try splitting it up now into separate functions so it's not all in main. Like I said, bools throw me a little so I tend to avoid them, making my life more difficult for myself.
What does g_ means?
ReplyDeleteI mention it at the bottom of my comments (they are in green), basically, I'm trying to get into the habit of pre-fixing global variables with g_(variablename). This is because global variables shouldn't really be used as they can be accessed anywhere from within the code (if you have them set to external as well) and if another programmer has to amend your work they could end up changing this variable. I don't always do it as I'm trying to avoid the use of global variables.
DeleteYou can stop the loop right away when you find a match
ReplyDeleteint checkIllegalDotw()
{
for (int i = 0; i < acceptedDays.size(); ++i)
{
if (g_inputDotw == acceptedDays[i])
{
++g_n;
}
}
return g_n;
}