-3

I'm currently working on a program that has a linked list. My program need to have a function that can sort all the data based on its months and then display all of the data but I can't find a good example for me to refer because in my case I need to search the string expireDate; which is input this way dd/mm/yyyy which means that I need to take its subtring by using std::string str2 = temp->expireDate.substr(3,2); in order for me to get the month and then convert the substring into integer using int month;. Please take a look at my code, it is sorted but it doesn't display anything when I run it, I think there must be a very little mistake. I've already figured out my mistakes, it's just a silly mistake actually. There's no error on this code tho.

carInsurance* remove_next(carInsurance* prev)// pass NULL if start_ptr is the Node to be removed
{
    if(prev)
    {
        if( prev->next )// ensure prev isn't pointing to the last Node in the list
        {
            carInsurance* temp = prev->next;// temp will be removed
            prev->next = temp->next;// link across temp
            return temp;
        }
    }
    else if(start_ptr)// ensure list not empty
    {
        carInsurance* temp = start_ptr;// start_ptr will be removed
        start_ptr = start_ptr->next;
        return temp;
    }

    return NULL;// if called on empty list, or if prev->next is NULL
}

void carInsurance::sortMonth(int *x) // sort by month in ascending order
{
    carInsurance *start_ptr2 = NULL;// head of sorted list
    float price, addPrice;

    while(start_ptr)// repeat until no nodes left in unsorted list
    {
        // pointers for iterating through the unsorted list
        carInsurance *prev = NULL;// always previous to the current node considered (below)
        carInsurance *curr = start_ptr;// start at beginning of list
        carInsurance *prevMax = NULL;// pointer to node before the node with the highest age
        int max = start_ptr->month;// 1st node holds max age to start

        while(curr)// iterate through the list
        {
            if(curr->month > max )// new highest age found
            {
                max = curr->month;// save new max age
                prevMax = prev;// save pointer to node before the max
            }
            prev = curr;// advance iterators
            curr = curr->next;
        }

        // Node with the highest age found this pass through the list.
        carInsurance *xferNode = remove_next(prevMax);// obtain node to be moved into sorted list
        if( xferNode )// check that it's not NULL
        {
            xferNode->next = start_ptr2;// add to beginning of sorted list
            start_ptr2 = xferNode;
        }
    }
    start_ptr = start_ptr2;// list now sorted. Reassign start_ptr to point to it.

    while(temp != NULL)// Display details for what temp points to
    {
        cout << "\n___Customer Information___\n" << endl;
        cout << "\nName : " << temp->name << endl;
        cout << "IC: "<< temp->iCno << endl;
        cout << "Date of Birth: " << temp->dob << endl;
        cout << "Nationality: " << temp->nationality << endl;
        cout << "Address: " << temp->address << endl;
        cout << "Mobile Number: " << temp->phoneNo << endl;
        cout << "Email: " << temp->email << endl;
        cout << "Occupation: " << temp->occupation << endl;

        cout << "\n_____Car Information_____\n" << endl;
        cout << "Car Plate Number: " << temp->carNo << endl;
        cout << "Insurance Expire Date: " << temp->expireDate << endl;
        cout << "Usage of Car Model/Make: " << temp->carUsage << endl;
        cout << "Manufacturing Date: " << temp->manufacturingDate << endl;

        cout << "\n___Insurance Information___\n" << endl;
        cout << "Insurance Package:" << endl;
        if(temp->package == 1)
        {
            cout << "\nPackage A (Comprehensive Cover)" << endl;
            cout << "\t-Covers losses or damages to your car due to accident, fire and theft    " << endl;
            cout << "\t-Covers Third Party death and bodily injuries                            " << endl;
            cout << "\t-Covers Third Party property losses or damages                           " << endl;
            price = 1000;

        }
        else if (temp->package == 2)
        {
            cout << "\nPackage B (Third Party Cover)" << endl;
            cout << "\t-Covers Third Party death and bodily injuries" << endl;
            cout << "\t-Covers Third Party property losses or damages" << endl;
            price = 1500;
        }
        else if (temp->package == 3)
        {
            cout << "\nPackage C (Third Party, Fire & Theft Cover)" << endl;
            cout << "\t-Covers losses or damages to your car due to fire or theft" << endl;
            cout << "\t-Covers Third Party death and bodily injuries" << endl;
            cout << "\t-Covers Third Party property losses or damages" << endl;
            price = 900;
        }
        else
        cout << "No package available" << endl;

        if(temp->additional == 1)
        {
            cout << "\nAdditional package: "<< endl;
            if (temp->option==1){
                cout << "Road tax renewal" << endl;
                addPrice = 50;
            }

            else if (temp->option==2){
                cout << "Name of second driver" << endl;
                addPrice = 0;
            }

            else if (temp->option==3){
                cout << "Windscreen coverage" << endl;
                addPrice = 20;
            }

            else if (temp->option==4){
                cout << "Rental reimbursement" << endl;
                addPrice = 50;
            }

            else if (temp->option==5){
                cout << "Roadside assistance or towing insurance" << endl;
                addPrice = 80;
            }

            else if (temp->option==6){
                cout << "Full glass coverage" << endl;
                addPrice = 70;
            }
            else
                cout << "Not availabe"<< endl;
            }
            else{
                cout << "No additional package" << endl;
                price = 0;
            }
            temp->insuranceAmount = price + addPrice;
            cout << "Amount to be insured: RM" << temp->insuranceAmount << endl;

            //temp = temp->next;
            }//End of While Loop
}//End of sortMonth
beginner
  • 57
  • 1
  • 10
  • There does not appear to be anything in the shown code that's related to sorting; rather it looks like the beginning of twelve nearly identical chunks of code. I think you will find some useful information that might help you [at this link](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik May 07 '18 at 03:06
  • Q: Is this the right way for me to sort it? A: Uh, no. SUGGESTION: Consider putting your data into a C++ [vector](http://www.cplusplus.com/reference/vector/vector/), and and try using [std::sort()](http://www.cplusplus.com/reference/algorithm/sort/). Here's an example: [Beginners guide to the std::sort() function](http://www.cplusplus.com/articles/NhA0RXSz/) – paulsm4 May 07 '18 at 03:18

1 Answers1

0

Are you allowed to use all of C++ or are you really only allowed to use C with std::string and std::cout?

If you can use C++ here is how I would do it (still using a linked list since you specified that in your question - std::vector and std::sort would be more performant if you don't need to use a linked list):

#include <iostream>
#include <sstream>
#include <iterator>
#include <locale>
#include <vector>
#include <list>

// define a facet that adds slash to the list of delimiters
class slash_is_space : public std::ctype<char> {
public:
    mask const *get_table() { 
        static std::vector<std::ctype<char>::mask> 
            table(classic_table(), classic_table()+table_size);
        table['/'] = (mask)space;
        return &table[0];
    }
    slash_is_space(size_t refs=0) : std::ctype<char>(get_table(), false, refs) { }
};

// define a class (with public members) that adds splits the date using the new facet
struct extract_date
{
    int day, month, year;
    extract_date(std::string date) {
        std::stringstream ss(date);
        ss.imbue(std::locale(std::locale(), new slash_is_space));
        ss >> day >> month >> year;
    }
};

// your struct containing the date that will be used for sorting
struct carInsurance
{
    std::string carNo;
    std::string expireDate;
    std::string carUsage;
    std::string manufacturingDate;
};

// a function that can print your struct
std::ostream& operator << ( std::ostream& out, const carInsurance& rhs )
{
    out << rhs.carNo      << ", "
        << rhs.expireDate << ", "
        << rhs.carUsage   << ", "
        << rhs.manufacturingDate;
    return out;
}

int main()
{
    // your linked list of data
    std::list<carInsurance> cars{{"a","00/01/0000","a","a"},
                                 {"b","00/03/0000","b","b"},
                                 {"c","00/02/0000","c","c"}};

    // sort the list by expireDate month
    cars.sort([](carInsurance& a, carInsurance& b){
        extract_date a_date(a.expireDate);
        extract_date b_date(b.expireDate);
        return a_date.month < b_date.month;
    });

    // print the sorted list
    std::copy(cars.begin(), cars.end(), std::ostream_iterator<carInsurance>(std::cout, "\n"));

    return 0;
}
Jerry Jeremiah
  • 9,045
  • 2
  • 23
  • 32
  • If I use this method do I need to change the way I input all of my data in the linked list too? if you want to take a look at my [full code click this](https://github.com/vrncjss/crybaby/blob/master/main) – beginner May 07 '18 at 07:05
  • also I'm confused with the `struct carInsurance` and my `class carInsurance` because I'm using a class to make this linked list – beginner May 07 '18 at 07:35
  • @beginner `struct { blah }` is the same as `class { public: blah }` and `class { blah }` is really just `class { private: blah }` so struct makes all the members public by default. I did it to make the code shorter but in a real program you would probably have accessors. – Jerry Jeremiah May 08 '18 at 03:35
  • @beginner If it is homework then are you allowed to use std::list or do you have to make your own linked list? If it isn't homework you should might want to consider if you need a linked list or whether a vector would be better. – Jerry Jeremiah May 08 '18 at 03:38
  • @beginner I will add something that inputs the linked list data instead of having it hardcoded. – Jerry Jeremiah May 08 '18 at 03:38
  • @beginner In your full code you do many things that seem wrong. For example this line ` phoneNo[15] = carInsurance_phoneNo[15];` doesn't do what you think it does - what it actually does is only copy the 16th character in the source array to the 16th character in the destination array but you only defined the array to have 15 characters with indexes from 0 to 14. What you probably were thinking you wanted was strcpy but what you really need to do is make all those character arrays into std::string and then you can assign them with an equals sign. – Jerry Jeremiah May 08 '18 at 03:44
  • I will make another answer that helps with your full code. – Jerry Jeremiah May 08 '18 at 03:45
  • actually I found a new way, when I input the data I took the substring of the month and then I convert the substring into integer, and I have found a way for me to sort it but I've some problem with the sorting that it doesn't display anything after sorting is done. – beginner May 08 '18 at 07:41
  • actually this is my project. This project require us to use linked list in class – beginner May 08 '18 at 07:43
  • but why does it work perfectly when I input and display it? for the ` phoneNo[15] = carInsurance_phoneNo[15];` – beginner May 08 '18 at 08:48
  • @JerryJeremiah I had not though about using facet and locale to make >> operators do custom parsing. Adding that to my bag of tricks, thanks. – r_ahlskog May 08 '18 at 10:12
  • @JerryJeremiah I am able to sort and display it already. Thank you for your time. :) – beginner May 08 '18 at 10:56
  • I got warning: _array subscript is above array bounds_ . Is this what you meant by the ` phoneNo[15] = carInsurance_phoneNo[15]; `? – beginner May 08 '18 at 14:30
  • @beginner Yes. It should not be a warning - accessing memory you don't own creates undefined behaviour - usually crashing the program sometime later in some other function but just as equally it can cause time travel https://blogs.msdn.microsoft.com/oldnewthing/20140627-00/?p=633 or anything else the compiler feels like. – Jerry Jeremiah May 09 '18 at 05:38