Reno
Reno

Reputation: 1139

How to use array with pointer?

I am new to programming and an trying to create an array with a series of records in and then have the programme accept input and finally print out the contents of the list.

I am having trouble recording the values of some of the variables in my addRecord() function as the output of the code below is the following:

constructor called
-1:-1 Eat lunch

-1:-1 Watch TV

destructor called

Why am I missing the call to L1.addRecord(5, 30, "Make dinner"); completely and why aren't the times coming through (they are coming through as -1 which is set in the constructor)?

Thank you

#include <iostream>
#include <string>
using namespace std;

class Record {
private:
    int hour;
    int minute;
    string todo;

public:
    Record()
    {
        hour = -1;
        minute = -1;
        todo = "N/A";
    }

    void setData(int hour, int minute, const char* td);
    void setData(Record& e);
    void printRecord();
};

class List
{
private:
    Record* recordArr;
    int maxRecords;
    int actualRecordCount;

public:
    List(int maxRecords);

    List(List& s) {
        actualRecordCount = s.actualRecordCount;
        maxRecords = s.maxRecords;
        recordArr = new Record[maxRecords];
        for (int i = 0; i < actualRecordCount; i++)
        {
            recordArr[i].setData(s.recordArr[i]);
        }

        std::cout << "copy constructor called." << std::endl;
    }
    ~List();
    bool addRecord(int hour, int minute, const char* todo);
    void printList();
};


///////////////////////////

void Record::setData(int hour, int minute, const char* td)
{
    hour = hour;
    minute = minute;
    todo = td;
}

void Record::setData(Record& e) 
{
    hour = e.hour; 
    minute = e.minute;
    todo = e.todo;
}

void Record::printRecord()
{
    std::cout << hour << ":" << minute << " " << todo << std::endl;
}

List::List(int maxRecords)
    : maxRecords(maxRecords)
{
    actualRecordCount = 0;
    recordArr = new  Record[maxRecords];
    std::cout << "constructor called" << std::endl;
}

List::~List()
{
    std::cout << "\ndestructor called";
    delete[] recordArr;
}

bool List::addRecord(int hour, int minute, const char* todo)
{
    Record newRecord; // create new Record
    newRecord.setData(hour, minute, todo); //assign values

    if (actualRecordCount >= maxRecords) // array full
    {
        return false;
    }

    else
    {
        recordArr[actualRecordCount] = newRecord; // put new Record into the array of Entry
        actualRecordCount++; // increment Entry count
        return true;
     }

}

void List::printList()
{
    for (int i = 0; i < actualRecordCount; i++)
    {
        recordArr[i].printRecord();
        cout << endl;
        i++;
    }

}

int main() {

    List L1(20);
    L1.addRecord(2, 30, "Eat lunch");
    L1.addRecord(5, 30, "Make dinner");
  L1.addRecord(7, 30, "Watch TV");
    L1.printList();

}

Upvotes: 1

Views: 70

Answers (3)

john
john

Reputation: 87959

The other error is here

void List::printList()
{
    for (int i = 0; i < actualRecordCount; i++)
    {
        recordArr[i].printRecord();
        cout << endl;
        i++;
    }

}

You have i++ twice.

Upvotes: 2

Adrian Mole
Adrian Mole

Reputation: 51825

One problem is that your Record::setData function with three arguments doesn't actually set the hour and minute fields of the class object! This is caused by your use of arguments with the same name as the class members, which (IMHO) is bad coding style. So, in the following code, your first two assignments just replace the argument values with themselves:

void Record::setData(int hour, int minute, const char* td)
{
    hour = hour;      // This and the following line are self-assignments to the arguments
    minute = minute;  // given and, as such, are effectively doing nothing!
    todo = td;        // This, however, is OK, because there is no ambiguity.
}

To fix this, either add an explicit this-> reference to the targets:

void Record::setData(int hour, int minute, const char* td)
{
    this->hour = hour;
    this->minute = minute;
    todo = td;
}

Or (much better, in my opinion) give the first two arguments non-ambiguous names:

void Record::setData(int in_hour, int in_minute, const char* td)
{
    hour = in_hour;
    minute = in_minute;
    todo = td;
}

Upvotes: 1

Sam Varshavchik
Sam Varshavchik

Reputation: 118300

void Record::setData(int hour, int minute, const char* td)
{
    hour = hour;

"hour" is the name of a parameter to this setData() method. hour=hour;, therefore, sets this parameter to itself. This accomplishes absolutely nothing, whatsoever. Same for other two assignments that follow.

Your obvious intent here is to initialize the class that happens to have members with the same name. When different things have the same name in C++ there's a complicated set of rules that choose which "thing" the name represents. These rules are the same on the left and the right side of the = operator, so both of these hours end up referring to the same object: the parameter to this class method.

You can simply rename the parameters to the method:

void Record::setData(int hourArg, int minuteArg, const char* tdArg)
{
    hour = hourArg;

and so on. Or, if you wish to keep the parameter names the same, make things more explicit:

this->hour=hour;

Upvotes: 3

Related Questions