-2

I have a shopping list in a c++ class that has the item name, price, and expiration date all combined into one object. How can I sort the list alphabetically in a member function?

This is my item class and isLessThan is the sort function

#include "item.h"

InventoryItem::InventoryItem()
{
        itemName = nullptr;
        itemPrice = 0;
        expDate = nullptr;
}

InventoryItem::InventoryItem(const InventoryItem& anItem):InventoryItem()
{
        *this = anItem;
}

InventoryItem::InventoryItem(InventoryItem&& anItem):InventoryItem()
{
        *this = move(anItem);
}

InventoryItem::~InventoryItem()
{
        if(this->itemName)
        {
                delete [] this->itemName;
                this->itemName = nullptr;
        }
        if(this->expDate)
        {
                delete this->expDate;
                this->expDate = nullptr;
        }
}


const InventoryItem& InventoryItem::operator=(const InventoryItem& anItem)
{
        if(this == &anItem)
        {
                return *this;
        }
        if(itemName)
        {
                delete [] itemName;
        }
        itemName = new char[strlen(anItem.itemName)+1];
        strcpy(itemName, anItem.itemName);
        itemPrice = anItem.itemPrice;
        if(expDate)
        {
                delete expDate;
        }
        expDate = new Date(*(anItem.expDate));

        return *this;
}

InventoryItem& InventoryItem::operator= (InventoryItem&& anItem)
{
        if(this == &anItem)
        {
                return *this;
        }
        if(itemName)
        {
                delete [] itemName;
        }
        itemName = anItem.itemName;
        anItem.itemName = nullptr;
        itemPrice = anItem.itemPrice;
        anItem.itemPrice = 0;
        if(expDate)
        {
                delete expDate;
        }
        expDate = anItem.expDate;
        anItem.expDate = nullptr;

        return *this;
}

void InventoryItem::setItemName(const char name[])
{
        if(this->itemName)
                delete [] this->itemName;
        this->itemName = new char[strlen(name)+1];
        strcpy(this->itemName, name);
}

const char* InventoryItem::getItemName() const
{
        return itemName;
}

void InventoryItem::setItemPrice(float price)
{
        itemPrice = price;
}

float InventoryItem::getItemPrice() const
{
        return itemPrice;
}

void InventoryItem::setExpDate(const Date& aDate)
{
        if(this->expDate)
                delete expDate;
        this->expDate = new Date(aDate);
}

const Date * InventoryItem::getExpDate() const
{
        return this->expDate;
}

void InventoryItem::print() const
{
        cout << fixed;
        cout.precision(2);
        cout << itemName << "\t" << itemPrice
                << "\t" << *expDate << endl;
}

bool InventoryItem::isLessThan(const InventoryItem& anItem){
        anItem.getItemName();

        return 0;
}

istream& operator>> (istream& in, InventoryItem& anItem)
{
        //assuming data input format "itemName:itemPrice:year/month/day"
        char    itemName[MAX_CHAR];
        float   itemPrice;
        Date    expDate;
        int             year;
        int             month;
        int     day;

        //read value in temporary variables
        in.get(itemName, MAX_CHAR, ':');
        in.get();                                       //throw away ':'
        in >> itemPrice;
        in.get();                                       //throw away ':'
        in >> year;
        in.get();                                       //throw away '/'
        in >> month;
        in.get();                                       //throw away '/'
        in >> day;

        in.ignore(MAX_CHAR, '\n');      //throw away '\n'

        //populate anItem with the temporary variables
        anItem.setItemName(itemName);
        anItem.setItemPrice(itemPrice);
        expDate.setDate(year, month, day);
        anItem.setExpDate(expDate);
        return in;
}
#include "itemList.h"
ItemList::ItemList()
{
        size = 0;
        capacity = INIT_CAPACITY;
        list = new InventoryItem[capacity];
}

ItemList::ItemList(const ItemList& aList)
{
        size = aList.size;
        capacity = aList.capacity;
        list = new InventoryItem[capacity];
        int index;
        for(index = 0; index < size; index++)
        {
                list[index] = aList.list[index];
        }
}

ItemList::ItemList(ItemList&& aList)
{
        this->size = aList.size;
        this->capacity = aList.capacity;
        this->list = aList.list;
        aList.list = nullptr;
        aList.size = 0;
        aList.capacity = 0;
}

ItemList::~ItemList()
{
        if(this->list)
        {
                delete [] this->list;
                this->list = nullptr;
        }
}
ItemList& ItemList::operator= (ItemList&& aList)
{
        if (this == &aList)
        {
                return *this;
        }
        this->size = aList.size;
        this->capacity = aList.capacity;
        if (this->list)
        {
                delete [] this->list;
        }
        this->list = aList.list;
        aList.list = nullptr;
        aList.size = 0;
        aList.capacity = 0;
        return *this;
}

const ItemList& ItemList::operator= (const ItemList& aList)
{
        if(this == &aList)
        {
                return *this;
        }
        size = aList.size;
        capacity = aList.capacity;
        if(list != nullptr)
        {
                delete [] list;
        }
        list = new InventoryItem[capacity];
        int index;
        for(index = 0; index < size; index++)
        {
                list[index] = aList.list[index];
        }
        return *this;
}

int ItemList::getSize() const
{
        return size;
}

InventoryItem& ItemList::operator[] (int index)
{
        return list[index];
}

const InventoryItem& ItemList::operator[] (int index) const
{
        return list[index];
}

void ItemList::expandArray()
{
        capacity = capacity * GROWTH_FACTOR;
        InventoryItem * tempList = new InventoryItem[capacity];
        int index;
        for(index = 0; index < size; index++)
        {
                tempList[index] = list[index];
        }
        delete [] list;
        list = tempList;
}

void ItemList::append(const InventoryItem& anItem)
{
        if(size == capacity)
        {
                expandArray();
        }
        list[size] = anItem;
        size++;
}

void ItemList::readList(istream& in)
{
        char                    itemName[MAX_CHAR];
        float                   itemPrice;
        Date                    expDate;
        int                             year;
        int                             month;
        int                             day;
        InventoryItem   anItem;

        in.get(itemName, MAX_CHAR, ':');
        while (!in.eof())
        {
                in.get();
                in >> itemPrice;
                in.get();
                in >> year;
                in.get();
                in >> month;
                in.get();
                in >> day;
                in.ignore(MAX_CHAR, '\n');

                anItem.setItemName(itemName);
                anItem.setItemPrice(itemPrice);
                expDate.setDate(year, month, day);
                anItem.setExpDate(expDate);

                append(anItem);

                in.get(itemName, MAX_CHAR, ':');
        }
}

bool ItemList::addItem(const InventoryItem& anItem){

        append(anItem);
        return true;
}

void ItemList::printList() const
{
        int index;
        for(index = 0; index < size; index++)
        {
                list[index].print();
        }
}

This is for school and I've been looking everywhere for an answer to this and I just can't find it. I can't use any STL headers

  • question is how can i sort the list alphabetically – waytotheworld Aug 18 '21 at 06:57
  • Sorry, but SO doesn't work this way. You should demonstrate your attempt first and ask a specific question. We're not going to do your homework. – Evg Aug 18 '21 at 06:59
  • Ok I'm sorry I'm new to this – waytotheworld Aug 18 '21 at 07:00
  • Then please read: [How do I ask a good question?](https://stackoverflow.com/help/how-to-ask) – Evg Aug 18 '21 at 07:01
  • You need to choose your sort algorithm – grigouille Aug 18 '21 at 07:02
  • @grigouille know I need to choose my sort algorithm but my main problem is I don't know how I can compare the values to run an algorithm – waytotheworld Aug 18 '21 at 07:14
  • Pick one from [here](https://stackoverflow.com/questions/24650626/how-to-implement-classic-sorting-algorithms-in-modern-c). Then implement the functions that it uses – Caleth Aug 18 '21 at 08:12
  • Offtopic: You should use the constructor's initialiser list (not to be confused with `std::initializer_list`) for initialising member variables: `InventoryItem::InventoryItem() : itemName(nullptr), itemPrice(0), expDate(nullptr) { }` to get direct initialisation instead of default-initialisation + assignment. While not really an issue here this can get significant if complex types are involved. And some types (references, const members, non-copiable types, ...) *only* can be initialised this way. – Aconcagua Aug 18 '21 at 08:48
  • Assigning members to `nullptr` in destructors is pretty much useless, the object is destroyed afterwards anyway. Why are you operating with dynamic arrays anyway? Using `std::string` instead of `char*` or `char const*` and `std::vector` instead of `InventoryItem*` releaves you from all the manual memory management you do now (and you can drop duplicate size and capacity information and use the vector's one); i. e. you don't need to manually write copy and move constructor and assignment, you get the right ones for free. – Aconcagua Aug 18 '21 at 08:54
  • @Aconcagua this has a "no std" requirement, probably homework – Caleth Aug 18 '21 at 09:03
  • @Caleth My bad, overlooked, sorry. – Aconcagua Aug 18 '21 at 18:11

1 Answers1

1

Assuming that you have something with the same interface as std::sort, you need a Compare function, e.g.

bool InventoryItemNameLess(const InventoryItem & lhs, const InventoryItem & rhs) {
    return std::strcmp(lhs.getItemName(), rhs.getItemName()) < 0;
}

Aside: The requirements are silly. It would be really nice to use std::string for the item names, because that has a useful <

Aconcagua
  • 24,880
  • 4
  • 34
  • 59
Caleth
  • 52,200
  • 2
  • 44
  • 75