So the program makes an inventory from a cvs file. The cvs file consists of dvds and books.
here is the code:
#include "StdAfx.h"
#define _CRTDBG_MAP_ALLOC //for memory checking
#include <iostream>
#include <stdlib.h>
#include <crtdbg.h>
#include <iomanip>
#include <fstream>
#include <string.h>
#pragma warning(disable: 4996 4018)
using namespace std;
#define COPYSTR(TARGET, SOURCE) \
TARGET = new char [strlen(SOURCE)+1]; \
strcpy(TARGET, SOURCE)
////////////////////////////////////////////////////////////////////-->ERROR
class error
{
fstream error_file;
void open_file();
void close_file();
public:
error() {open_file();}
~error() {close_file();}
void print_file();
void clear_file();
void add_file(int, const char*);
};
void error::open_file()
{
error_file.open("error_file.txt", ios::in | ios::out | ios::app);
}
void error::print_file()
{
cout << "\nERRORS:\n";
char temp[256];
if(error_file)
{
error_file.seekg(0,ios::beg);
while(!error_file.eof())
{
if(error_file.getline(temp,256))
cout << temp << endl;
}
}
}
void error::clear_file()
{
if(error_file.is_open())
error_file.close();
error_file.open("error_file.txt", ios::out);
error_file.close();
}
void error::close_file()
{
if(error_file.is_open())
error_file.close();
}
void error::add_file(int num, const char* error)
{
if(error_file)
{
error_file << num+1 << ": " << error <<endl;
}
else
cout << "unable to open";
}
////////////////////////////////////////////////////////////////////////-->CONTAINER
class container
{
public:
virtual void alloc_rows(int n_rows) = 0;
virtual void insert(void* i) = 0;
virtual const void* get(int i) const = 0;
virtual int get_n_rows() const = 0;
virtual ~container() = 0 {};
};
////////////////////////////////////////////////////////////////////////-->FILE_BUFF
class file_buff: public container
{
char** line;
int n_lines;
int count;
int process_file(const char* fn);
int count_lines(ifstream& file);
void delete_file_buff();
public:
file_buff(const char* fn) {process_file(fn);}
virtual ~file_buff() {delete_file_buff();}
int get_n_lines() const {return n_lines;}
const char* get_line(int index) const {return line[index];}
virtual void alloc_rows(int n_rows);
virtual void insert(void* thing);
virtual const void* get(int i) const {return get_line(i);}
virtual int get_n_rows() const {return get_n_lines();}
};
void file_buff::alloc_rows(int n_rows) {
n_lines = n_rows;
line = new char* [n_lines];
}
void file_buff::insert(void* thing){
char* temp = (char*)thing;
line[count] = new char [strlen(temp)+1];
strcpy(line[count], temp);
count++;
}
int file_buff::count_lines(ifstream& file)
{
int pos = 0;
char temp[256];
if (file.good()){
while (!file.eof())
if (file.getline(temp,256))
pos++;
file.clear();
file.seekg(0,ios::beg);
}
return pos;
}
int file_buff::process_file(const char* file)
{
char temp[256];
ifstream in;
in.open(file);
count = 0;
if (in.good()) {
alloc_rows(count_lines(in));
for(int i = 0; i < n_lines; i++)
line[i] = NULL;
while (!in.eof()) {
if (in.getline(temp, 256)) {
insert(temp);
}
}
}
else
{
cout << "Unable to open file " << file << endl;
cin.get();
exit(1);
}
in.close();
return count;
}
void file_buff::delete_file_buff()
{
int i=0;
if (line)
{
for(i=0; i < n_lines; i++)
{
delete [] line[i];
line[i] = NULL;
}
delete [] line;
line = NULL;
}
}
/////////////////////////////////////////////////////////////////////////-->ITEM
class item
{
char* title;
int item_num;
float price;
int year;
public:
item() : title(0), item_num(0), price(0), year(0) {};
virtual ~item();
void set_title(const char* f_title);
const char* get_title() const {return title;}
void set_item_num(int f_item_num) {item_num = f_item_num;}
int get_item_num() const {return item_num;}
void set_year(int f_year) {year = f_year;}
int get_year() const {return year;}
void set_price(float f_price) {price = f_price;}
float get_price() const {return price;}
static int compare_item_nums (const void* e1, const void* e2);
virtual float type_ship() const = 0;
virtual bool init (const char* temp, int num) = 0;
virtual ostream& print(ostream& out) = 0;
virtual item* clone() = 0;
virtual void show_detail() = 0;
};
void item::set_title(const char* f_title)
{
if(title)
delete [] title;
if(f_title == NULL)
title = NULL;
else
COPYSTR(title, f_title);
}
int item::compare_item_nums(const void* e1, const void* e2)
{
const item** ptr1 = (const item**) (e1);
const item** ptr2 = (const item**) (e2);
int i1 = (*ptr1)->get_item_num();
int i2 = (*ptr2)->get_item_num();
if(i1 > i2) return 1;
if(i1 < i2) return -1;
return 0;
}
ostream& operator << (ostream& out, item& i)
{
return i.print(out);
}
item::~item()
{
if(title) {
delete [] title;
title = NULL;
}
}
/////////////////////////////////////////////////////////////////////////-->BOOK
class book: public item
{
char* author;
char* isbn;
int num_pages;
char format;
void delete_book();
public:
book(): author(0), isbn(0), num_pages(0), format(0) {};
book (const book& cbk);
virtual ~book() {delete_book();}
void show_book();
void set_isbn(const char* f_isbn);
void set_author(const char* f_author);
const char* get_author() const {return author;}
const char* get_isbn() const {return isbn;}
book& operator= (const book& cbk);
friend ostream& operator << (ostream& lhs, book& cbk);
virtual float type_ship() const {return 3.00;}
virtual bool init(const char* buff, int num);
virtual ostream& print(ostream& out);
virtual item* clone() {return new book(*this);}
virtual void show_detail();
};
book::book(const book& cbk) : num_pages(cbk.num_pages), format(cbk.format)
{
set_item_num(cbk.get_item_num());
if(cbk.get_title())
set_title(cbk.get_title());
if(cbk.get_author())
set_author(cbk.get_author());
set_isbn(cbk.get_isbn());
set_year(cbk.get_year());
set_price(cbk.get_price());
}
book& book::operator = (const book& cbk)
{
if(this != &cbk)
{
set_title(cbk.get_title());
set_author(cbk.get_author());
set_year(cbk.get_year());
set_item_num(cbk.get_item_num());
set_price(cbk.get_price());
format = cbk.format;
num_pages = cbk.num_pages;
}
return *this;
}
ostream& operator << (ostream& lhs, book& cbk)
{
return cbk.print(lhs);
}
ostream& book::print(ostream& out)
{
cout << "Item " << get_item_num() << " \"" << get_title();
cout << "\" by " << get_author() << ". $";
cout << fixed << setprecision(2) << get_price() << endl;
return out;
}
void book::set_isbn(const char* f_isbn)
{
if(isbn)
delete [] isbn;
if(f_isbn == NULL)
isbn = NULL;
else
COPYSTR(isbn, f_isbn);
}
void book::set_author(const char* f_author)
{
if(author)
delete [] author;
if(f_author == NULL)
author = NULL;
else
COPYSTR(author, f_author);
}
bool book::init(const char* buff, int num)
{
error txt;
char temp[256];
strcpy(temp, buff);
char* fitem_num = strtok(temp, ",");
if(strlen(fitem_num) != 4) {
txt.add_file(num+1,"item number must have 4 digits");
return false;}
if(fitem_num[0] != '4') {
return false;}
set_item_num(atoi(fitem_num));
char* fisbn = strtok(NULL, ",");
set_isbn(fisbn);
if(strlen(isbn)>10||strlen(isbn)<9) {
txt.add_file(num+1,"isbn must be 10 or least digits");
return false;}
char* ftitle = strtok(NULL, ",");
set_title(ftitle);
char* fauthor = strtok(NULL, ",");
set_author(fauthor);
char* fyear = strtok(NULL, ",");
if(strlen(fyear)!=4 || atoi(fyear)==0){
txt.add_file(num+1,"year must be 4 digits");
return false;}
set_year(atoi(fyear));
char* fformat = strtok(NULL, ",");
format = *fformat;
if(!(format=='H'||format=='P') || strlen(fformat)!=1){
txt.add_file(num+1,"format must be P or H");
return false;}
char* fnum_pages = strtok(NULL, ",");
if(atoi(fnum_pages)<=0){
txt.add_file(num+1,"number of pages must be more than 0");
return false;}
num_pages = atoi(fnum_pages);
float price;
char* fprice = strtok(NULL, "\n");
sscanf(fprice, "%f", &price);
if(price<=0){
txt.add_file(num,"price can't be less than 0");
return false;}
set_price(price);
return true;
}
void book::show_book()
{
cout << "Item " << get_item_num() << ": ";
cout << "\"" << get_title() << "\" by " << get_author() << ". $";
cout << fixed << setprecision(2) << get_price() << endl;
}
void book::show_detail()
{
cout << "Item # " << get_item_num() << endl;
cout << "----------" << endl;
cout << "Title: " << get_title() << endl;
cout << "Author: " << get_author() << endl;
cout << "Format: ";
if(format == 'P')
cout << "Paperback" << endl;
else
cout << "Hardback" << endl;
cout << "Year: " << get_year() << endl;
cout << "Pages: " << num_pages << endl;
cout << "ISBN: " << get_isbn() << endl;
cout << "Price: $" << get_price() << endl;
}
void book::delete_book()
{
if (author) {
delete [] author;
author = NULL;
}
if (isbn) {
delete [] isbn;
isbn = NULL;
}
}
/////////////////////////////////////////////////////////////////////////-->DVD
class dvd: public item
{
char* upc;
char* star1;
char* star2;
void delete_dvd();
public:
dvd(): upc(0), star1(0), star2(0) {};
dvd(const dvd& cdv);
virtual ~dvd() {delete_dvd();}
void show_dvd();
void set_upc(const char* f_upc);
const char* get_upc() const {return upc;}
void set_star1(const char* f_star1);
const char* get_star1() const {return star1;}
void set_star2(const char* f_star2);
const char* get_star2() const {return star2;}
dvd& operator = (dvd&);
friend ostream& operator << (ostream& out, item& cdv);
virtual float type_ship() const {return 1.00;}
virtual bool init(const char* buff, int num);
virtual ostream& print(ostream& out);
virtual item* clone() {return new dvd (*this);}
virtual void show_detail();
};
dvd::dvd(const dvd& cdv)
{
set_item_num(cdv.get_item_num());
if(cdv.get_title())
set_title(cdv.get_title());
if(cdv.get_star1())
set_star1(cdv.get_star1());
if(cdv.get_star2())
set_star2(cdv.get_star2());
if(cdv.get_upc())
set_upc(cdv.get_upc());
set_year(cdv.get_year());
set_price(cdv.get_price());
}
dvd& dvd::operator = (dvd& cdv)
{
if(this != &cdv)
{
set_title(cdv.get_title());
set_item_num(cdv.get_item_num());
set_year(cdv.get_year());
set_star1(cdv.get_star1());
set_star2(cdv.get_star2());
set_upc(cdv.get_upc());
set_price(cdv.get_price());
}
return *this;
}
ostream& operator << (ostream& lhs, dvd& cdv)
{
return cdv.print(lhs);
}
ostream& dvd::print(ostream& out)
{
cout << "Item " << get_item_num() << " \"" << get_title();
cout << "\" <" << get_year() << "> starring: " << get_star1() << " and " << get_star2();
cout << ". $" << fixed << setprecision(2) << get_price() << endl;
return out;
}
void dvd::set_upc(const char* f_upc)
{
if(upc)
delete [] upc;
if(f_upc == NULL)
upc = NULL;
else
COPYSTR(upc, f_upc);
}
void dvd::set_star1(const char* f_star1)
{
if(star1)
delete [] star1;
if(f_star1 == NULL)
star1 = NULL;
else
COPYSTR(star1, f_star1);
}
void dvd::set_star2(const char* f_star2)
{
if(star2)
delete [] star2;
if(f_star2 == NULL)
star2 = NULL;
else
COPYSTR(star2, f_star2);
}
bool dvd::init(const char* buff, int num)
{
error txt;
char temp[256];
strcpy(temp, buff);
char* fitem_num = strtok(temp, ",");
if(strlen(fitem_num) != 4){
txt.add_file(num+1,"item number must have 4 digits");
return false;}
if(fitem_num[0] != 7)
return false;
set_item_num(atoi(fitem_num));
char* fupc = strtok(NULL, ",");
set_upc(fupc);
if(strlen(fupc)>12||strlen(fupc)<11){
txt.add_file(num+1,"upc must be 12 digits");
return false;}
char* ftitle = strtok(NULL, ",");
set_title(ftitle);
char* fyear = strtok(NULL, ",");
if(strlen(fyear)!=4 || atoi(fyear)>0){
txt.add_file(num+1,"year must be 4 digits");
return false;}
set_year(atoi(fyear));
char* fstar1 = strtok(NULL, ",");
set_star1(fstar1);
char* fstar2 = strtok(NULL, ",");
set_star2(fstar2);
float price;
char* fprice = strtok(NULL, "\n");
sscanf(fprice, "%f", &price);
if(price<=0){
txt.add_file(num,"price can't be less than 0");
return false;}
set_price(price);
return true;
}
void dvd::show_dvd()
{
cout << "Item " << get_item_num() << ": " << "\"" << get_title() << "\" <" << get_year() << ">";
cout << " Staring: " << star1 << " and " << star2 << ". $" << fixed << setprecision(2) << get_price() << endl;
}
void dvd::show_detail()
{
cout << "Item # " << get_item_num() << endl;
cout << "----------" << endl;
cout << "Title: " << get_title() << endl;
cout << "Year: " << get_year() << endl;
cout << "UPC: " << get_upc() << endl;
cout << "Starring: " << get_star1() << " and " << get_star2() << endl;
cout << "Price: $" << get_price() << endl;
}
void dvd::delete_dvd()
{
if(upc) {
delete [] upc;
upc = NULL;
}
if(star1) {
delete [] star1;
star1 = NULL;
}
if(star2) {
delete [] star2;
star2 = NULL;
}
}
////////////////////////////////////////////////////////////////////-->ITEM_HOLDER
class item_holder: public container
{
item** arr_items;
int n_items;
const int max;
public:
void init_ary(int n);
item_holder(int n): n_items(0), max(n) {init_ary(n);};
virtual ~item_holder() {delete_ary();}
void delete_ary();
void set_n_items(int n) {n_items = n;}
int get_n_items() const {return n_items;}
item* get_item(int i) const {return arr_items[i];}
int search_item(int i);
void sort_item_nums();
bool add_item_ih(item* item_ptr);
virtual void alloc_rows(int n_rows) {init_ary(n_rows);}
virtual void insert(void* thing) {add_item_ih((item*)thing);}
virtual const void* get(int i) const {return get_item(i);}
virtual int get_n_rows() const {return n_items;}
};
void item_holder::init_ary(int n)
{
arr_items = new item* [n];
for (int i = 0; i < n; i++)
arr_items[i] = NULL;
}
void item_holder::delete_ary()
{
if(arr_items)
{
for(int i = 0; i < n_items; i++)
{
if(arr_items[i])
{
delete arr_items[i];
arr_items[i] = NULL;
}
}
delete [] arr_items;
arr_items = NULL;
}
}
int item_holder::search_item(int i)
{
for(int j = 0; j < n_items; j++)
{
if(arr_items[j]->get_item_num() == i)
return j;
}
return -1;
}
void item_holder::sort_item_nums()
{
qsort(arr_items, n_items, sizeof(item*), &item::compare_item_nums);
}
bool item_holder::add_item_ih(item* item_ptr)
{
if(n_items = max)
return false;
arr_items[n_items] = item_ptr->clone();
n_items++;
return true;
}
////////////////////////////////////////////////////////////////////--> CART
class cart: public item_holder
{
public:
cart(): item_holder(10) {};
virtual ~cart() {delete_ary();}
void show_cart();
};
void cart::show_cart()
{
double subt = 0.0;
double ship = 0.0;
double rate = 0.0825;
double tax = 0.0;
cout << "Cart\t" << endl;
for(int i = 0; i < get_n_items(); i++)
{
cout << *(get_item(i));
subt += get_item(i)->get_price();
ship += get_item(i)->type_ship();
}
tax = rate*(subt+ship);
cout << "\n\nSubtotal: \t" << subt << endl;
cout << "Shipping: \t" << ship << endl;
cout << "Taxes: \t" << tax << endl;
cout << "Total: \t" << subt+ship+tax << endl;
}
////////////////////////////////////////////////////////////////////-->INVENTORY
class inventory: public item_holder
{
bool add_item_inv_bk(const char* buff, int num);
bool add_item_inv_dv(const char* buff, int num);
public:
inventory(int n): item_holder(n) {};
virtual ~inventory() {delete_ary();}
void fill_inventory(container* cp);
void show_inventory();
};
bool inventory::add_item_inv_bk(const char* buff, int num)
{
error txt;
item* pbook = new book;
if(pbook->init(buff, num))
{
if(search_item(pbook->get_item_num()) == -1)
{
bool i_ptr = add_item_ih(pbook);
delete pbook;
return i_ptr;
}
else
{
txt.add_file(num+1, "item number already exists");
delete pbook;
return false;
}
}
delete pbook;
return false;
}
bool inventory::add_item_inv_dv(const char* buff, int num)
{
error txt;
item* pdvd = new dvd;
if(pdvd->init(buff, num))
{
if(search_item(pdvd->get_item_num()) == -1)
{
bool i_ptr = add_item_ih(pdvd);
delete pdvd;
return i_ptr;
}
else
{
txt.add_file(num+1, "item number already exists");
delete pdvd;
return false;
}
}
delete pdvd;
return false;
}
void inventory::fill_inventory(container* cp)
{
int current = 0;
for (current = 0; current < cp->get_n_rows(); current++)
{
char type = ((char*)cp->get(current))[0];
if(type == '4')
{
if(!(add_item_inv_bk((char*)cp->get(current),current)))
continue;
}
else if(type == '7')
{
if(!(add_item_inv_dv((char*)cp->get(current),current)))
continue;
}
else
{
error txt;
txt.add_file(current+1, "invalid inventory entry");
}
} return;
}
void inventory::show_inventory()
{
sort_item_nums();
cout << "\nBOOKS" << endl;
for(int i = 0; i < get_n_items(); i++)
{
if(get_item(i)->get_item_num() > 4999)
{
cout << "\nDVDS" << endl;
}
cout << *(get_item(i));
}
cout << endl;
}
////////////////////////////////////////////////////////////////////////////////-->MENU
class menu_manager
...
////////////////////////////////////////////////////////////////////////////////-->MAIN
void main()
{
{
const char* FILE_NAME = "inventory1.csv";
cout <<"Processing file from: " << FILE_NAME << "...\n\n";
container* fb = new file_buff(FILE_NAME);
inventory inv(fb->get_n_rows());
inv.fill_inventory(fb);
error txt;
txt.print_file();
txt.clear_file();
menu_manager mgr(inv);
mgr.manage();
delete fb;
}
_CrtDumpMemoryLeaks(); //check for mem leaks
cout << "\nPress Enter to Exit...";
cin.get();
}
The problems appear at:
(1)
class item
{
variables
...
public:
...
-->>int get_item_num() const {return item_num;}
...
};
(2)
int item_holder::search_item(int i)
{
for(int j = 0; j < n_items; j++)
{
if(arr_items[j]->get_item_num() == i)
return j;
}
return -1;
}
And consequently all the functions that use item_holder::search_item
which are:
class inventory: public item_holder
{
bool add_item_inv_bk(const char* buff, int num);
bool add_item_inv_dv(const char* buff, int num);
...
}
best regards,
JE821.