Question
CPSC-131 Project 3: Universal Product Code (UPC) Catalog This project is different from the previous two. In project 1, you were not allowed to use
CPSC-131 Project 3: Universal Product Code (UPC) Catalog
This project is different from the previous two. In project 1, you were not allowed to use the C++ Standard Library (SL); in project 2, you were allowed but not required to use the SL. In this project, you are required to use the SL map, std::map, to apply this binary search tree to a real problem.
The project files provide one class, Catalog, with member functions that you must complete and which is expected to include the map.
Universal Product Code (UPC)
A Universal Product Code (UPC) has four parts but this project deals with only two of them: category number and product number. Categories are groups of related products, such as books or toys. They have numbers, which must be unique, and names, which dont have to be unique but usually are. Each product in a category also has a number and a name. Product numbers must be unique within a category but may be reused in separate categories. Product names, like category names, dont have to be unique.
Application
The project requires the design and implementation of an application program that creates an catalog of UPCs for a store and provides access to that catalog. The catalog is loaded from a text file that contains Category and Product records. Here is a sample:
Category 78292 Books (Hard-Cover)
5931 Gone With the Wind
15897 to Kill a Mockingbird
232 The Adventures of Tom Sawyer
Category 78162 Toys
9577 Sleepytime Gal Barbie Collector Doll
23890 Tonka Classis Mighty Dump Truck
572 Ambi Toys Chirpy Bird Whistle
Category 40506 Jewelry
48610 Ring
2389 Necklace
34901 Bracelet
Each category record has three fields: the Category tag, a number, and a name. They are separated by tab characters (in C++, the tab character is represented by \t); the format is Category-tab-number-tab-name.
Each product record has two fields: number and name. They are separated by tab characters; the format is number-tab-name.
Category and product names can have multiple words separated by spaces.
Category and product records may be in any order and may not be in a continuous sequence.
Classes and Functions
The program must have a Catalog class with the indicated functions:
1. AddCategory: Given a category number and name, add it to the catalog. It will have an empty product list. Return false if the category number already exists in the catalog, true otherwise.
2.AddProduct: Given a category number, a product number, and a product name, add the product to the catalog. Return false if the category number doesnt exist in the catalog or if the product number already exists within the category, true otherwise.
3.GetCategoryCount: Return the number of categories in the catalog.
4.GetProductCount: Given a category number, return the number of products in the category; return -1 if the category doesnt exist.
5.Load: Load the catalog from a file, given the files name. Return false if the catalog cant be loaded, either because the file doesnt exist or isnt in the correct format.
6.ShowAll: Show the entire catalog, category by category, in order by category number. Under each category, show its products in order by product number. Use the same format as the text file in Load.
7.ShowCategory: Given a category number, show only its products in order by product number. Return false if the category number doesnt exist in the catalog. Use the same format as the text file in Load.
8.ShowProduct: Given a category number and a product number, show the product number and name separated by a tab. Return false if the category number doesnt exist in the catalog or if the product number doesnt exist within the category.
The output format of the three Show... functions should be the same as the input file format. These functions are designed so that their caller specifies an output stream, which may be cout, a file, or a stringstream. The prolog comments for each function explains more about output streams.
Resources
Program Files
These files will be posted on GitHub for you to download, use or modify, and submit:
-Catalog.h: contains declarations of the Catalog class. You may add other declarations as needed for your implementation. Do not add definitions (code) to this file; definitions of functions belong in catalog.cpp. [TO BE COMPLETED]
-Catalog.cpp: contains skeletons for the required member functions. You may add other functions, member and nonmember, as needed for your implementation. [TO BE COMPLETED]
-Main.cpp: contains a set of test functions that will call Catalogs functions. You may modify this file for your own test purposes but use the original file to run your final test before you submit your project
These files are used by main.cpp to read test files. You should not change these files function but you may use its functions in your code if you wish.
-GetLine.cpp and GetLine.h: contain a function similar to the Standard Librarys getline(stream, string) function. This version handles the variety of line breaks that can appear in text files, depending on the application that created them.
Test Files
Two test files will be posted on GitHub for you to download: SmallCatalog.txt and LargeCatalog.txt. They contain lists of categories and products. SmallCatalog.txts list is the same as the one shown above in the Application section; LargeCatalog.txt contains over a dozen categories and hundreds of products. Your final submittal will be tested using different files.
References
Two files will be posted on Titanium for your use:
-map.pdf, which describe SL classes of interest. It contains a brief description of the relevant map functionsinsert, find, eraseincluding how to insert a key/value pair.
-stringparsing.pptx, which shows how to parse the fields of a string to extract them one at a time. It describes how to find the beginning and end of fields that are separated by characters such as tabs, and how to copy each field substring into another string.
-A more extension description of the SL map class and its functions can be found at http://www.cplusplus.com/reference/map/map/.
-To convert strings to numbers, you can use std::stoi()
-To split an input stream using a delimiter (such as the tab character), you can use std::getline()
---------------------------------------------------------------------------------------------------------------------------------
Catalog.h
#ifndef Catalog_h | |
#define Catalog_h | |
//**************************************************************************************** | |
// | |
// INCLUDE FILES | |
// | |
//**************************************************************************************** | |
#include | |
#include | |
using namespace std; | |
//**************************************************************************************** | |
// | |
// CONSTANT DEFINITIONS | |
// | |
//**************************************************************************************** | |
//**************************************************************************************** | |
// | |
// CLASSES, TYPEDEFS AND STRUCTURES | |
// | |
//**************************************************************************************** | |
class Catalog | |
{ | |
public: | |
//Given a category number and name, add it to the catalog. It will have an empty product list. | |
//Return false if the category number already exists in the catalog, true otherwise. | |
bool AddCategory(uint64_t categoryNumber, const string& name); | |
| |
//Return the number of categories in the catalog | |
uint64_t GetCategoryCount(); | |
//Given a category number, a product number, and a product name, add the product to the catalog. | |
//Return false if the category number doesnt exist in the catalog or if the product number already exists within the category, true otherwise. | |
bool AddProduct(uint64_t categoryNumber, uint64_t productNumber, const string& name); | |
| |
//Given a category number, return the number of products in the category; return -1 if the category doesnt exist. | |
int64_t GetProductCount(uint64_t categoryNumber); | |
| |
//Load the catalog from a file, given the files name. | |
//Return false if the catalog cant be loaded, either because the file doesnt exist or isnt in the correct format. | |
bool Load(const string& fileName); | |
| |
//Given a category number and a product number, show the product number and name separated by a tab. | |
//Return false if the category number doesnt exist in the catalog or if the product number doesnt exist within the category. | |
bool ShowProduct(ostream& stream, uint64_t categoryNumber, uint64_t productNumber); | |
//Given a category number, show only its products in order by product number. | |
//Return false if the category number doesnt exist in the catalog.Use the same format as the text file in Load. | |
bool ShowCategory(ostream& stream, uint64_t categoryNumber); | |
//Show the entire catalog, category by category, in order by category number.Under each category, show its products in order by product number.Use the same format as the text file in Load. | |
bool ShowAll(ostream& stream); | |
private: | |
| |
// map declaration goes here | |
}; | |
//**************************************************************************************** | |
// | |
// FUNCTION PROTOTYPES | |
// | |
//**************************************************************************************** | |
#endif |
Catalog.cpp
//**************************************************************************************** |
// INCLUDE FILES |
// |
//**************************************************************************************** |
#include |
#include |
#include |
#include "Catalog.h" |
using namespace std; |
bool Catalog::AddCategory(uint64_t categoryNumber, const string& name) |
{ |
// to be completed |
return true; |
} |
bool Catalog::AddProduct(uint64_t categoryNumber, uint64_t productNumber, const string& name) |
{ |
// to be completed |
return true; |
} |
uint64_t Catalog::GetCategoryCount() |
{ |
// to be completed |
return 0; |
} |
int64_t Catalog::GetProductCount(uint64_t categoryNumber) |
{ |
// to be completed |
return 1; |
} |
bool Catalog::Load(const string& fileName) |
{ |
// to be completed |
return true; |
} |
//**************************************************************************************** |
// |
// Show... methods |
// |
// The stream argument allows thess functions to write its output to any output stream, |
// such as cout or a file, that the caller passes. The argument's name "stream" should |
// be used just as you would use "cout": |
// |
// stream << "X = " << x << endl; |
// |
// The output will go where the caller intended without special action by this function. |
// |
//**************************************************************************************** |
bool Catalog::ShowProduct(ostream& stream, uint64_t categoryNumber, uint64_t productNumber) |
{ |
// to be completed |
return true; |
} |
bool Catalog::ShowCategory(ostream& stream, uint64_t categoryNumber) |
{ |
// to be completed |
return true; |
} |
bool Catalog::ShowAll(ostream& stream) |
{ |
// to be completed |
return true; |
} |
Main.cpp
//**************************************************************************************** |
// INCLUDE FILES |
// |
//**************************************************************************************** |
#include |
#include |
#include |
#include "Catalog.h" |
using namespace std; |
bool Catalog::AddCategory(uint64_t categoryNumber, const string& name) |
{ |
// to be completed |
return true; |
} |
bool Catalog::AddProduct(uint64_t categoryNumber, uint64_t productNumber, const string& name) |
{ |
// to be completed |
return true; |
} |
uint64_t Catalog::GetCategoryCount() |
{ |
// to be completed |
return 0; |
} |
int64_t Catalog::GetProductCount(uint64_t categoryNumber) |
{ |
// to be completed |
return 1; |
} |
bool Catalog::Load(const string& fileName) |
{ |
// to be completed |
return true; |
} |
//**************************************************************************************** |
// |
// Show... methods |
// |
// The stream argument allows thess functions to write its output to any output stream, |
// such as cout or a file, that the caller passes. The argument's name "stream" should |
// be used just as you would use "cout": |
// |
// stream << "X = " << x << endl; |
// |
// The output will go where the caller intended without special action by this function. |
// |
//**************************************************************************************** |
bool Catalog::ShowProduct(ostream& stream, uint64_t categoryNumber, uint64_t productNumber) |
{ |
// to be completed |
return true; |
} |
bool Catalog::ShowCategory(ostream& stream, uint64_t categoryNumber) |
{ |
// to be completed |
return true; |
} |
bool Catalog::ShowAll(ostream& stream) |
{ |
// to be completed |
return true; |
} |
GetLine.h
// DO NOT EDIT THIS FILE | |
#ifndef GetLine_h | |
#define GetLine_h | |
//**************************************************************************************** | |
// INCLUDE FILES | |
#include | |
#include | |
using namespace std; | |
//**************************************************************************************** | |
// CONSTANT DEFINITIONS | |
//**************************************************************************************** | |
// CLASSES, TYPEDEFS AND STRUCTURES | |
//**************************************************************************************** | |
// FUNCTION PROTOTYPES | |
bool GetLine(istream& stream, string& text); | |
bool GetLine(istream& stream, string& text, const string& delimiter); | |
#endif |
GetLine.cpp
// DO NOT EDIT THIS FILE | |
//**************************************************************************************** | |
// | |
// INCLUDE FILES | |
// | |
//**************************************************************************************** | |
#include | |
#include | |
#include "GetLine.h" | |
using namespace std; | |
//**************************************************************************************** | |
// | |
// CONSTANT DEFINITIONS | |
// | |
//**************************************************************************************** | |
//**************************************************************************************** | |
// | |
// CLASSES, TYPEDEFS AND STRUCTURES | |
// | |
//**************************************************************************************** | |
//**************************************************************************************** | |
// | |
// MACROS | |
// | |
//**************************************************************************************** | |
//**************************************************************************************** | |
// | |
// PUBLIC DATA | |
// | |
//**************************************************************************************** | |
//**************************************************************************************** | |
// | |
// PRIVATE DATA | |
// | |
//**************************************************************************************** | |
//**************************************************************************************** | |
// | |
// FUNCTION PROTOTYPES | |
// | |
//**************************************************************************************** | |
//**************************************************************************************** | |
// | |
// GetLine | |
// | |
// This function reads a series of characters from a stream and puts it into a string, | |
// stopping when it sees a line break: | |
// 1. A carriage return (CR) | |
// 2. A line feed (LF) | |
// 3. A CR/LF pair | |
// 4. A LF/CR pair | |
// The #3 and #4 pairs are a single line break. | |
// The line break (any of the four) is consumed but not added to the output string. | |
// | |
// The return status is true if at least one character, which can be a line break, is read; | |
// the status is false if an end-of-file is immediately encountered. | |
// | |
//**************************************************************************************** | |
bool GetLine(istream& stream, string& text) | |
{ | |
//************************************************************************************ | |
// LOCAL DATA | |
int c; | |
| |
int p; | |
| |
bool success; | |
//************************************************************************************ | |
// EXECUTABLE STATEMENTS | |
text.erase(); | |
success = false; | |
while (true) | |
{ | |
c = stream.get(); | |
if (stream.good()) | |
{ | |
success = true; | |
| |
if (c == ' ') | |
{ | |
p = stream.peek(); | |
if (p == ' ') | |
{ | |
stream.ignore(); | |
} | |
break; | |
} | |
else if (c == ' ') | |
{ | |
p = stream.peek(); | |
if (p == ' ') | |
{ | |
stream.ignore(); | |
} | |
break; | |
} | |
else | |
{ | |
text += c; | |
} | |
} | |
else | |
{ | |
break; | |
} | |
} | |
// If we reached the end of file, but at least one character was seen, | |
// including any delimiter, clear the stream's state so the caller won't | |
// ignore the last line of a file. | |
if (success) | |
{ | |
stream.clear(); | |
} | |
return(success); | |
} | |
//**************************************************************************************** | |
// | |
// GetLine | |
// | |
// This function reads a series of characters from a stream and puts it into a string, | |
// stopping when it sees any character from a specified delimiter set. The delimiter | |
// is consumed but not added to the output string. | |
// | |
//**************************************************************************************** | |
bool GetLine(istream& stream, string& text, const string& delimiter) | |
{ | |
//************************************************************************************ | |
// LOCAL DATA | |
const uint32_t initialMask = 0x80000000; | |
const uint32_t columnMask = 0x1F; | |
const uint32_t rowMask = 0x07; | |
const uint32_t rowShift = 5; | |
char c; | |
uint32_t flag[8]; | |
uint32_t i; | |
uint32_t mask; | |
uint32_t row; | |
uint32_t shift; | |
bool success; | |
//************************************************************************************ | |
// EXECUTABLE STATEMENTS | |
text.erase(); | |
// Set up flags array. | |
for (row = 0; row < (sizeof(flag) / sizeof(flag[0])); ++row) | |
{ | |
flag[row] = 0; | |
} | |
for (i = 0; i < delimiter.size(); ++i) | |
{ | |
c = delimiter[i]; | |
row = (c >> rowShift) & rowMask; | |
shift = c & columnMask; | |
mask = initialMask >> shift; | |
flag[row] |= mask; | |
} | |
// Get characters until a delimiter is seen or the end of the file | |
// is reached. | |
success = false; | |
while (true) | |
{ | |
stream.get(c); | |
if (stream.good()) | |
{ | |
// Remember that at least one character has been seen. | |
success = true; | |
// Check for a delimiter. | |
row = (c >> rowShift) & rowMask; | |
shift = c & columnMask; | |
mask = initialMask >> shift; | |
if ((flag[row] & mask) == 0) | |
{ | |
// Character isn't a delimiter, save it. | |
text += c; | |
} | |
else | |
{ | |
// Character is a delimiter, leave loop. | |
break; | |
} | |
} | |
else | |
{ | |
break; | |
} | |
} | |
// If we reached the end of file, but at least one character was seen, | |
// including any delimiter, clear the stream's state so the caller won't | |
// ignore the last line of a file. | |
if (success) | |
{ | |
stream.clear(); | |
} | |
return(success); | |
} |
SmallCatalog.txt
5931 Gone With The Wind | ||
15897 To Kill a Mockingbird | ||
232 The Adventures of Tom Sawyer | ||
Category 78162 Toys | ||
9577 Sleepytime Gal Barbie Collector Doll | ||
23890 Tonka Classic Mighty Dump Truck | ||
573 Ambi Toys Chirpy Bird Whistle | ||
Category 40506 Jewelry | ||
48610 Ring | ||
2389 Necklace | ||
34901 Bracelet |
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started