230 lines
5.2 KiB
C++
230 lines
5.2 KiB
C++
/* Cody Cook
|
|
2023/04/13
|
|
CS-210 Project 3
|
|
*/
|
|
#include "Items.h"
|
|
|
|
// constructors
|
|
|
|
// default constructor; parses default file name
|
|
Items::Items()
|
|
{
|
|
if (!ParseInputFile())
|
|
{
|
|
// try getting a new file
|
|
RequestNewFile();
|
|
}
|
|
}
|
|
|
|
// constructor with a custom input option
|
|
Items::Items(string p_inputFile = defaultItemFileName)
|
|
{
|
|
SetInputFile(p_inputFile);
|
|
if (!ParseInputFile())
|
|
{
|
|
// try geting a new file
|
|
RequestNewFile();
|
|
}
|
|
}
|
|
|
|
// destructors
|
|
|
|
// run a set of functions when the class closes
|
|
Items::~Items()
|
|
{
|
|
if (r_input.is_open())
|
|
{
|
|
r_input.close();
|
|
}
|
|
}
|
|
|
|
// getters
|
|
|
|
// prints and returns the inventory for a named item
|
|
int Items::GetInventory(string p_item)
|
|
{
|
|
// search the string in the map
|
|
auto it = r_mapping.find(p_item);
|
|
|
|
// if there were results
|
|
if (it != r_mapping.end())
|
|
{
|
|
string times; // allow for more natural responses with the word "time"
|
|
|
|
// if there is only one item, it is only there "one time"
|
|
if (it->second == 1)
|
|
{
|
|
times = " time.";
|
|
}
|
|
else
|
|
{
|
|
// if it is 0 or 2 or more, then it is "times"
|
|
times = " times.";
|
|
}
|
|
|
|
// output the quantity purchased
|
|
cout << c_red << it->first << c_normal
|
|
<< " were purchased ";
|
|
cout << c_red << it->second << c_normal;
|
|
cout << times << endl;
|
|
return it->second;
|
|
}
|
|
else
|
|
{
|
|
// because there wasn't quantity, explain it wasn't purchased.
|
|
cerr << c_red << p_item << c_normal
|
|
<< " were not purchased." << endl;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
// return the string for the inputFile
|
|
string Items::GetInputFile()
|
|
{
|
|
return r_inputFile;
|
|
}
|
|
|
|
char Items::GetStar()
|
|
{
|
|
return r_star;
|
|
}
|
|
|
|
// setters
|
|
|
|
// update the filename of the input file
|
|
void Items::SetInputFile(string p_inputFile)
|
|
{
|
|
r_inputFile = p_inputFile;
|
|
}
|
|
|
|
// change the star used in the histogram
|
|
void Items::SetStar(char p_star)
|
|
{
|
|
r_star = p_star;
|
|
}
|
|
|
|
// methods
|
|
|
|
// ParseInputFile reads the input file and stores the data in a map; it also runs a backup of the data
|
|
bool Items::ParseInputFile()
|
|
{
|
|
// try opening the file
|
|
r_input.open(r_inputFile);
|
|
|
|
// if the file could not be opened
|
|
if (!r_input.is_open())
|
|
{
|
|
// error out
|
|
cout << "Error opening file "
|
|
<< c_red << r_inputFile << c_normal << endl;
|
|
return false;
|
|
}
|
|
clog << endl
|
|
<< "Parsing "
|
|
<< c_red << r_inputFile << c_normal
|
|
<< "... ";
|
|
|
|
string line;
|
|
// while we go through each line of the file
|
|
while (getline(r_input, line))
|
|
{
|
|
// Increment the frequency of the current line into the map
|
|
r_mapping[line]++;
|
|
}
|
|
// close the file
|
|
r_input.close();
|
|
|
|
// run a backup of this data and return true
|
|
SaveInventory();
|
|
return true;
|
|
}
|
|
|
|
// output the inventory based on the config
|
|
void Items::PrintInventory(int p_type)
|
|
{
|
|
// find the length of the longest item to help align the output
|
|
size_t longest = 0;
|
|
for (const auto &entry : r_mapping)
|
|
{
|
|
if (entry.first.length() > longest)
|
|
{
|
|
longest = entry.first.length();
|
|
}
|
|
}
|
|
|
|
// output the inventory
|
|
for (const auto &entry : r_mapping)
|
|
{
|
|
// output the item name with the longest item name as the width
|
|
cout << setw(longest) << entry.first << " ";
|
|
|
|
// see the quantity as a number
|
|
if (p_type == 1)
|
|
{
|
|
cout << c_red << entry.second << c_normal << endl;
|
|
}
|
|
// see the quantity as a histogram
|
|
else if (p_type == 2)
|
|
{
|
|
cout << c_red << string(entry.second, r_star) << c_normal << endl;
|
|
}
|
|
}
|
|
}
|
|
|
|
// SaveInventory creates a backup of the data in the map
|
|
bool Items::SaveInventory()
|
|
{
|
|
// open file for backup
|
|
ofstream file(r_database);
|
|
|
|
// if the file isn't open
|
|
if (!file.is_open())
|
|
{
|
|
// then there was a opening the file; so warn the user and exit the function
|
|
cerr << "Error opening " << c_red << r_database << c_normal << " for backup. Please check your permissions.";
|
|
return false;
|
|
}
|
|
|
|
// iterate through the mappings and save them to the file
|
|
for (const auto &entry : r_mapping)
|
|
{
|
|
file << entry.first << " " << entry.second << endl;
|
|
}
|
|
|
|
// save and close the file
|
|
file.close();
|
|
|
|
// output a successful save and return true
|
|
cout << "Backup file "
|
|
<< c_red << r_database << c_normal
|
|
<< " updated." << endl;
|
|
cout << endl;
|
|
return true;
|
|
}
|
|
|
|
void Items::RequestNewFile()
|
|
{
|
|
string newFile;
|
|
bool moveOn = false;
|
|
while (!moveOn)
|
|
{
|
|
cout << endl;
|
|
cout << "Type " << c_red << "exit" << c_normal << " to quit, or enter the filename to import: ";
|
|
cout << c_red;
|
|
cin >> newFile;
|
|
cout << c_normal;
|
|
|
|
if (newFile == "exit")
|
|
{
|
|
exit(0);
|
|
}
|
|
|
|
SetInputFile(newFile);
|
|
|
|
if (ParseInputFile())
|
|
{
|
|
moveOn = true;
|
|
}
|
|
}
|
|
}
|