I chose to enter 4 months during runtime.

I decided to test out the member functions/dynamic feature of linked lists, by then adding 3 months before compile time (static binding), which would be appear after the first 4 months.

The program outputs:

Full list again:
Month January, had [double input at run time] inches of rainfall
Month February, had [double input at run time] inches of rainfall
Month [b]July[/b], had 4 inches of rainfall
Month [b]June[/b], had 2 inches of rainfall
Month March, had [double input at run time] inches of rainfall
Month April, had [double input at run time] inches of rainfall
Month May, had 3 inches of rainfall

Why isn't June and July displayed after May?
Keep in mind, May, June, July would be the 3 months added, after choosing to enter 4 months.

I think the culprit comes from overload the < operator, in Rainfall_stat.h file.

bool operator < (const Rainfall_stats &right)    // Overloaded < 
    {  
        bool status; 

        if (month < right.month) 
            status = true; 
        //else if (month == right.month && amount < right.amount) 
        //  status = true;
        else 
            status = false;

        return status; 
    }

I switched the status = true & status = false statements

bool operator < (const Rainfall_stats &right)    // Overloaded < 
    {  
        bool status; 

        if (month < right.month) 
            status = false; 
        //else if (month == right.month && amount < right.amount) 
        //  status = true;
        else 
            status = true;

        return status; 
    }

Got the following output:

Full list again:
Month May, had 3 inches of rainfall
Month [b]June[/b], had 2 inches of rainfall
Month [b]July[/b], had 4 inches of rainfall
Month January, had [double input at run time] inches of rainfall
Month February, had [double input at run time] inches of rainfall
Month March, had [double input at run time] inches of rainfall
Month April, had [double input at run time] inches of rainfall

Full program code

int main

#include <iostream>
#include <string>

#include "Listing.h" 
#include "Rainfall_stats.h" 
using namespace std;

int main()
{
    Listing<Rainfall_stats>list;

    string monthNames[] = {"January","Febuary","March","April","May","June","July","August","September","October","November", "December"};
    int numMonths;
    double rainAmount;

    cout << "How many months do you want to enter data for (1 thorugh 12): ";
    cin >> numMonths;


    Rainfall_stats * temp = new Rainfall_stats[numMonths];

    int i = 0;
    for(i = 0; i < numMonths; i++)
    {
        cout << "Rainfall amount for " << monthNames[i] << ": ";
        cin >> rainAmount;

        temp[i] = Rainfall_stats(monthNames[i], rainAmount);
        list.appendNode(temp[i]);
    }

    cout << "i amount: " << i;

    // Display the values in the list. 
    cout << "\nHere are the initial values:\n";
    list.displayList(); 
    cout << endl;

    cout << "Adding another month's data...";
    Rainfall_stats temp2(monthNames[i], 3); // I had to overload > and < relational operators
    list.insertNode(temp2);                     // logical error, line 40 isn't placed last, in line 44's output.

    Rainfall_stats temp3(monthNames[i+1], 2);   // I had to overload > and < relational operators
    list.insertNode(temp3); 

    Rainfall_stats temp4(monthNames[i+2], 4);   // I had to overload > and < relational operators
    list.insertNode(temp4); 

    cout << "\nFull list again:\n";
    list.displayList(); 
    cout << endl;

    delete [] temp;

    system("pause");
    return 0;
}

Rainfall_stats.h

#include <iostream>
#include <string>

#include "Listing.h" 
#include "Rainfall_stats.h" 
using namespace std;

int main()
{
    Listing<Rainfall_stats>list;

    string monthNames[] = {"January","Febuary","March","April","May","June","July","August","September","October","November", "December"};
    int numMonths;
    double rainAmount;

    cout << "How many months do you want to enter data for (1 thorugh 12): ";
    cin >> numMonths;


    Rainfall_stats * temp = new Rainfall_stats[numMonths];

    int i = 0;
    for(i = 0; i < numMonths; i++)
    {
        cout << "Rainfall amount for " << monthNames[i] << ": ";
        cin >> rainAmount;

        temp[i] = Rainfall_stats(monthNames[i], rainAmount);
        list.appendNode(temp[i]);
    }

    cout << "i amount: " << i;

    // Display the values in the list. 
    cout << "\nHere are the initial values:\n";
    list.displayList(); 
    cout << endl;

    cout << "Adding another month's data...";
    Rainfall_stats temp2(monthNames[i], 3); // I had to overload > and < relational operators
    list.insertNode(temp2);                     // logical error, line 40 isn't placed last, in line 44's output.

    Rainfall_stats temp3(monthNames[i+1], 2);   // I had to overload > and < relational operators
    list.insertNode(temp3); 

    Rainfall_stats temp4(monthNames[i+2], 4);   // I had to overload > and < relational operators
    list.insertNode(temp4); 

    cout << "\nFull list again:\n";
    list.displayList(); 
    cout << endl;

    delete [] temp;

    system("pause");
    return 0;
}

Rainfall_stats.h

// Specification file for the NumberList class 
#ifndef Rainfall_stats_H 
#define Rainfall_stats_H
//#include <cstdlib> 
#include <iostream>      // for NULL
#include <string>
using namespace std;

class Rainfall_stats 
{ 
private: 
    string month;
    double amount;

public: 
    // Constructor: notice the constructor initializes the head pointer to NULL (0)
    // This establishes an empty linked list. 
    Rainfall_stats() 
    {   month = "January";  
        amount = 0;         } 

    // Destructor: destroys  the list by deleting all its nodes. 
    Rainfall_stats(string m, double a)
    {   
        month = m;
        amount = a;
    }

    // Linked list operations 
    // These functions are defined in NumberList.cpp.
    void setMonth(string m)
    {
        month = m;
    }

    void setAmount(double a)
    {
        amount = a;
    }

    string getMonth() const
    {
        return month;
    }

    double getAmount() const
    {
        return amount;
    }


    bool operator < (const Rainfall_stats &right)    // Overloaded <, called by line 134's while loop in Listing.h
    {  
        bool status; 

        if (month > right.month) 
            status = true; 
        else 
            status = false;

        return status; 
    }


    //bool operator < (const Rainfall_stats &right)  // Overloaded < 
    //{  
    //  bool status; 

    //  if (month < right.month) 
    //      status = true; 
    //  else 
    //      status = false;
    //  
    //  return status; 
    //}


    friend ostream &operator << (ostream &strm, const Rainfall_stats &obj) 
    { 
        strm << "Month " << obj.month << ", had " << obj.amount << " inches of rainfall"; 
        return strm; 
    }
}; 
#endif 

Listing.h

// A class template for holding a linked list. 
//The limitation of the NumberList class is that it can only hold double values.

#ifndef LISTING_H 
#define LISTING_H 
#include <iostream>  // For cout and NULL 
using namespace std; 

template <class T> 
class Listing 
{ 
private: 
    // Declare a structure for the list. 
    struct ListNode 
    { 
        T value;                    // The value in this node
        struct ListNode *next;      // To point to the next node 
    }; 

    ListNode *head; // List head pointer 

public: 
    // Constructor : Renamed from NumberList to LinkedList
    Listing() 
        {   head = NULL;    } 

    // Destructor : Renamed from NumberList to LinkedList
    ~Listing();
    //{;}

    // Linked list operations 
    void appendNode(T); 
    void insertNode(T); 
    void deleteNode(T);
    void displayList() const; 
};

// Note that the template uses the ==, !=, and < relational operators to compare node values, 
// and it uses the << (line 93) operator with cout to display node values. Any type passed to  
// the template must support these operators. 


//********************************************************
// appendNode appends a node containing the value 
// passed into newValue, to the end of the list. 
//******************************************************** 
template <class T> 
void Listing<T>::appendNode(T newValue) 
{ 
    ListNode *newNode;      // To point to a new node 
    ListNode *nodePtr;      // To move through the list 


    // Allocate a new node and store nurn there. 
    newNode = new ListNode; 
    newNode->value = newValue;
    newNode->next = NULL; 

    // If there are no nodes in the list make newNode the 1st node. 
    if(!head) 
        head = newNode; 
    // Otherwise, insert newNode at end.
    else 
    { 
        // Initialize nodePtr to head of list. 
        nodePtr = head; 

        // Find the last node in the list. 
        while (nodePtr->next) 
            nodePtr = nodePtr->next; 

        // Insert newNode as the last node. 
        nodePtr->next = newNode; 
    }
}

//************************************************** 
// displayList shows the value 
// stored in each node of the linked list 
// pointed to by head. 
//************************************************** 
template <class T> 
void Listing<T>::displayList() const
{ 
    // To move through the list
    ListNode *nodePtr;

    // Position nodePtr at the head of the list. 
    nodePtr = head;     

    // While nodeptr points to a node, traverse the list. 
    while (nodePtr)     
    { 
        // Display the value in this node. 
        cout << nodePtr->value << endl; 

        // Move to the next node. 
        nodePtr = nodePtr->next; 
    }
}

//*****************************************************
// The insertNode function inserts a node with 
// newValue copied to its value member. 
//*****************************************************
template <class T> 
void Listing<T>::insertNode(T newValue) 
{
    ListNode *newNode;              // A new node 
    ListNode *nodePtr;              // To traverse the list 
    ListNode *previousNode = NULL;  // The previous node 


    // Allocate a new node and store num there. 
    newNode = new ListNode; 
    newNode->value = newValue; 

    // If there are no nodes in the list make newNode the first node. 
    if(!head) 
    { 
        head = newNode; 
        newNode->next = NULL; 
    } 
    // Otherwise, insert newNode. 
    else 
    { 
        // position nodePtr at the head of list. 
        nodePtr = head; 

        // Initialize previousNode to NULL. 
        previousNode = NULL; 

        // Skip all nodes whose value is less than num. 
        while (nodePtr != NULL && nodePtr->value < newValue) // will need < overloaded
        { 
            previousNode = nodePtr; 
            nodePtr = nodePtr->next; 
        }

         /*If the new node is to be the 1st in the list, 
         insert it before all other nodes.*/ 
        if (previousNode == NULL) 
        {
            head = newNode; 
            newNode->next = nodePtr; 
        }

        else // Otherwise insert after the previous node. 
        { 
            previousNode->next = newNode; 
            newNode->next = nodePtr; 
        } 
    } 
} 

//******************************************************** 
// The deleteNode function searches for a node • 
// with searchValue as its value. The node, if found, * 
// is deleted from the l ist and from memory. * 
//******************************************************** 
template <class T> 
void Listing<T>::deleteNode(T searchValue) 
{ 
    ListNode *nodePtr;          // To traverse the list 
    ListNode *previousNode;     // To point to the previous node

    // If the list is empty, do nothing. 
    if (!head) 
        return; 
    // Determine if the first node is the one. 
    if (head->value == searchValue) 
    { 
        nodePtr = head->next; 
        delete head; 
        head = nodePtr; 
    } 
    else 
    { 
        // Initialize nodePtr to head of list. 
        nodePtr = head; 

        // Skip a11 nodes whose value member is not equal to num.
        while (nodePtr != NULL && nodePtr->value != searchValue) 
        { 
            previousNode = nodePtr; 
            nodePtr = nodePtr->next;
        } 

        // If nodePtr is not at the end of the list, link the prevLous
        // node to the node after nodePtr, then delete nodePtr.
        if (nodePtr) 
        {
            previousNode->next = nodePtr->next; 
            delete nodePtr;
        }
    } 
} 


//******************************************************** 
// Destructor 
// This function deletes every node in the list.
//******************************************************** 
template <class T> 
Listing<T>::~Listing() 
{ 
    ListNode *nodePtr;      // To traverse the list 
    ListNode *nextNode;     // To point to the next node 

    // position nodePtr at the head of the list. 
    nodePtr = head; 

    // While nodePtr is not at the end of the list... 
    while (nodePtr != NULL) 
    { 
        // Save a pointer to the next node . 
        nextNode = nodePtr->next; 
        // Delete the current node. 
        delete nodePtr; 
        // position nodePtr at the next node . 
        nodePtr = nextNode; 
    } 
}
#endif 

Recommended Answers

All 2 Replies

You get those results because you base your sorting on the "name" of the month.

Well... The months of the year are obviously not in alphabetical order. So thats gonna get quite messy.

To get the desired result, you have to sort the months by number, instead of name.

You could say I don't want it to sort anything at all; only by when each record is 1st entered.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.