ADT's Saving objects to the class

Please help, I am stuck.

Please see below my code.

I am trying to create a ADT file for the class, thus the reason for the interface file, implantation file and then the main file. My problem is in the Main File.

I want to create an array of classes. For example, there are 9 phone calls made so I want to create 9 objects in the class PhoneCalls.

Each object needs to have its own variables namely: name, length and rate.

These objects are derived from the import file MyCalls.dat.

Firstly, I don't know if I am creating the CallsMade array correctly.

Secondly, when I try to use the >> operator that I created in the implementation and interface file, to store the values to the CallsMade my program just stops running

I cant figure out how to use the friend >> operator to save the value of tempName, tempLenght, tempRate from the main file into the header class.

**

  • INTERFACE FILE

**

//Header file Question_5_pCall.h: This is the INTERFACE for the class PhoneCall
#ifndef QUESTION_5_PCALL_H_INCLUDED
#define QUESTION_5_PCALL_H_INCLUDED
#include <iostream>
#include <string>
#include <fstream>

using namespace std;


class PhoneCall //Create the class PhoneCall
{
    private: //Create the private member variables
        string number;
        int length;
        float rate;
        float charged;


    public: //Create the public member variables
        PhoneCall (); //Create the default constructor
        ~PhoneCall();//Destructor that does not perform any action

        //Overload the stream extraction operators
        friend istream& operator >> (istream& ins, PhoneCall& callData);
        friend ostream& operator << (ostream& outs, const PhoneCall& callData);
};

#endif //QUESTION_5_PCALL_H_INCLUDED

**

  • IMPLEMENTATION FILE

**

//Implementation file Question_5_pCall.cpp
#include <iostream>
#include <cstdlib>
#include <string>
#include <fstream>
#include "Question_5_pCall.h"

using namespace std;

//Set default constructors values to empty, 0 and 0.
PhoneCall::PhoneCall() : number(""), length(0), rate(0), charged(0)
{
    //Body intentionally empty
}
//Set default destructor
PhoneCall::~PhoneCall()
{
    //Body intentionally empty
}

//Use overload stream operators
istream& operator >> (istream& ins, PhoneCall& callData)
{
    ins >> callData.number;
    ins >> callData.length;
    ins >> callData.rate;
    return ins;
}
ostream& operator <<(ostream& outs, const PhoneCall& callData)
{
    outs << callData.number << endl;
    outs << callData.length << endl;
    outs << callData.rate << endl;
    outs << callData.charged << endl; 
    return outs;
}

**

  • MAIN FILE

**

//Main file Question_5.cpp
#include <iostream>
#include <string>
#include <fstream>
#include <cstdlib>
#include <sstream>
#include "Question_5_pCall.h"

using namespace std;

void getTotalCallsMade (int & numOfCalls)
{//First lets see how many calls where made.
//Import the file

    ifstream inStreamMyCalls;
    inStreamMyCalls.open("MyCalls.dat");
    if (inStreamMyCalls.fail()) //Fail safe to check if file is run
    {
        cout << "Input file opening failed." << endl;
        exit(1);
    }
    string tempInfo;

    while (!inStreamMyCalls.eof())
    {
        getline(inStreamMyCalls, tempInfo);
        numOfCalls++;
    }
    inStreamMyCalls.close();
}

void getReadMyCalls (string data[], int numOfCalls)
{//Import the data and save on each line
    ifstream inStreamMyCalls;
    inStreamMyCalls.open("MyCalls.dat");
    if (inStreamMyCalls.fail()) //Fail safe to check if file is run
    {
        cout << "Input file opening failed." << endl;
        exit(1);
    }
    string tempInfo;

    int k=0;
    while (!inStreamMyCalls.eof())
    {
        getline(inStreamMyCalls, tempInfo);
        data[k] = tempInfo;
        //cout << data[k] <<endl;
        k++;
    }
    inStreamMyCalls.close();
}

void getInfo (string data, string & tempName, int & tempLength, float & tempRate)
{//Devide the data into Name, Length and rate for each call
    //Convert length to int and rate to float
    //Import the file

    int firstSpace, secondSpace, secondStart, thirdStart, totalLength;

        firstSpace = data.find(" ");
        secondSpace = data.find(" ", (firstSpace+1));
        totalLength = data.length();
        secondStart = firstSpace+1;
        thirdStart = secondSpace+1;
        string tempLe = "";
        string tempRa = "";


        for (int i = 0; i < firstSpace; i++)
            tempName = tempName + data[i];
        for (int i = secondStart; i < secondSpace; i++)
        {
            tempLe = tempLe + data[i];
        }
        for (int i = thirdStart; i < totalLength; i++)
            tempRa = tempRa + data[i];

        tempLength = atoi(tempLe.c_str());
        tempRate = atof(tempRa.c_str());
}

//THIS IS THE PROBLEM AREA
void storeInfo (int i, string tempName, int tempLenght, float tempRate)
{//Store the data into the class for each call made
    cout << tempName << " " << tempLenght << " " << tempRate << endl; //Double check to see if info is correct
    cin >> callsMade[i];
}
//PROBLEM AREA 


int main()
{
    string inputNumber;
    int numOfCalls = 0;

    getTotalCallsMade(numOfCalls);

    string data[numOfCalls];
    PhoneCall callsMade[numOfCalls];

    getReadMyCalls(data, numOfCalls);

    string tempName;
    int tempLength;
    float tempRate;
    string tempData;
    for (int i = 0; i < numOfCalls; i++)
    {
        tempData = data[i];
        getInfo(tempData, tempName, tempLength, tempRate);

        //PROBLEM AREA
        storeInfo(i, tempName, tempLength, tempRate);
        //PROBLEM AREA

        tempData = "";
        tempName = "";
        tempLength = 0;
        tempRate = 0.0;
    }

    return 0;
}
  • MyCalls.dat
0123452347 12 3.50
0337698210 9 3.15
0214672341 2 1.75
0337698210 15 3.15
0442389132 8 1.75
0232189726 5 3.50
0124395623 6 3.50
0337698210 2 3.15
0337698210 5 3.15

Thank you in advance

Edit - Updated the as per recommendations received from comments to make the code clear, update my question and also add the problematic code. Edit - Update the >> operator to ony install 3 variables and not 4.

1 answer

  • answered 2020-09-28 11:58 john

    So there's a lot to unpack here, but I think fundamentally you are confused about how operator>> works.

    Your code is reading the file into a string, parsing that string into the different variables, and then you are stuck trying to figure how to use the operator>> with the variables you have. But this is the wrong approach, you are actually doing a lot of the work that operator>> will do for you. The correct code is much simpler.

    You see operator>> works directly on the file and puts data directly into the object. There's no need for you to read and parse the file separately. Here's how the code should look

    PhoneCall callsMade[numOfCalls];
    ifstream inStreamMyCalls;
    inStreamMyCalls.open("MyCalls.dat");
    for (int i = 0; i < numOfCalls; i++)
    {
        inStreamMyCalls >> callsMade[i];
    }
    inStreamMyCalls.close();
    

    That's it, you can get rid of the data array, and all the temp... variables.

    Now after you've got the above working there still a few issues to deal with.

    Most important is that your operator>> reads three values but your operator<< writes four. As a matter of good design operator>> should be able to read what operator<< writes. They should complement each other in other words and that's not the case here. Not sure what should be done about that, maybe charged should be moved somewhere else. That's for you to decide.

    The way you read the file once to work out how many calls you have is not ideal. Really your code should be smart enough to be able to read the file only once and grow any data structure you have to accommodate the number of calls you read. You will find using a std::vector<PhoneCall> helpful here, much easier than using an array.

    In fact your array code PhoneCall callsMade[numOfCalls]; is not legal C++, because in C++ array bounds must be compile time constants. Now many compilers don't enforce this rule but nevertheless your current code is not legal C++ and some compilers would reject it. Again std::vector is the easy solution to this issue.