Answered step by step
Verified Expert Solution
Link Copied!

Question

1 Approved Answer

The Numbers Module Your task for this lab is to complete the implementation of the Numbers class. This class reads several double values from a

The Numbers Module

Your task for this lab is to complete the implementation of the Numbers class. This class reads several double values from a file (one number per line) and holds them dynamically in memory. Then the caller application has the option of adding numbers to the collection. This Module can provide information about the numbers and display them on the screen:
 

  • The Module can display the values in ascending order (sort).
  • The Module can find the largest value
  • The Module can find the smallest value
  • The Module can calculate the average of the values in the collection

Also The Numbers class has the following capabilities:

  • Numbers object can safely be copied or assigned to another Numbers module
  • Numbers object can be displayed or streamed into an istream object.
  • Numbers object can be read from an istream object.

When the Numbers object goes out of the scope the values overwrite the old values in the file, ONLY IF the object is the original object and not a copy.

The Numbers class

The Numbers class has four attributes:

 double* m_numbers; // holds the address of the dynamic array of doubles holding the number collection    

char* m_filename;  // holds the name of the file associated with the class (if it is the original object and not a copy)    

bool m_isOriginal; // flags if this object is the original (and not a copy)    

int m_numCount; // holds the number of values in the m_number dynamic array

Constructors, Destructor and Copy Assignment

The Numbers class can be instantiated in three different ways:

One argument constructor (implemented)

Creates an original instance of the Numbers class by receiving the data file name as a constant Cstring

  • Sets the object to safe empty state (setEmpty()).
  • Sets the m_isOriginal flag to true.
  • Sets the filename of the class (setFilename())
  • Sets the number of the double values to be read from the file (sets m_numCount using numberCount())

Now if the number of double values in file is greater than zero it tries to read the values from the file using the load() function as follows:

  • If m_numCount is greater than zero and load() is successful, the values will be sorted.
  • If not successful, it will free the memory pointed by m_numbers and m_filename
  • sets the object back the safe empty state and sets the class NOT TO BE original anymore.

Default constructor (implemented)

  Account();

  • Sets the object to safe empty state (setEmpty()).
  • Sets the m_isOriginal flag to false.

Destructor (implemented)

  • Saves the values in the file
  • deletes the memory pointed by m_numbers and m_filename

Copy Constructor (to be implemented)

  • Sets the object to safe empty state
  • Sets the object NOT to be original
  • Assigns the current object to the Numbers object that is being copied. (calls the Copy Assignment Operator)

Copy Assignment Operator (to be implemented)

  • deletes the current collection of the double values
  • Allocates new memory pointed by m_numbers to the number of the values in the object that is being copied.
  • Copies all the double values in the object that is being copied into the newly allocated memory.
  • returns the reference of the current object.

Member Functions and Member operator+= overloadisEmpty() (implemented)

returns true if m_numbers is null

setEmpty() (implemented)

sets m_numbers and m_filename to nullptr. sets m_numCount to zero.

setFilename() (implemented)

  • Receives a constant Cstring for the data file name.
  • Frees the memory pointed by m_filename pointer
  • Allocates memory to hold the data file name as a Cstring.
  • Copies the data file name to the newly allocated memory.

sort() (implemented)

Sorts the double values in ascending order

max() (implemented)

Returns the largest double number in the list

min() (implemented)

Returns the smallest double number in the list

average() (implemented)

Returns the average of the double numbers in the list.

numberCount() (to be implemented)

This function (that is incapable of modifying the correct object), will return the number of lines in the data file (hence returning the number of double values in the file).

  • Create an instance of ifstream to open the data file name.
  • While the ifstream object has not failed keep reading single characters from the file
  • Count the number of newline characters in an integer variable
  • Return the number of counted newlines when all characters in the file are scanned.

load() (to be implemented)

This function returns true if all the double values are read from the data file and stored in a dynamically alocated memory pointed by m_numbers, othewise returns false.

  • If number of double values in the file is greater than zero (m_numCount > 0)
  • Allocate memory to hold the double values in an array pointed by m_numbers.
  • Create an instance of ifstream for the data file
  • While the ifstream object has not failed, keep reading double values from the file into the elements of m_numbers dynamic array (as you do with cin)
     

make sure to add to the index of the loop only if the istream object has not failed in its last reading

  • return true if the number of read doubles, is equal to the m_numCount member variable.

save() (to be implemented)

  • If the current object is the original and it is not in safe empty state
  • Create an instance of ofstream to overwrite the dat afile
  • Write all the elements of the m_numbers array using the ofstream object.
  • Write a newline after each double value.

Operator += (to be implemented)

Overload the += operator to add a single double value to the list of numbers in the array and then return the reference of the current object.

You need to increase the size of the allocated memory by one (add one double to the array), to be able to do this.

Here is the sequence of the actions to be taken to resize memory:

  • Create a temporary local double pointer and allocate memory with the increased size
  • Copy all the current values to the newly allocated memory.
  • Update the size of the data to the new size
  • Now that all the values are copied to the new memory, delete the original allocated memory
  • Set the original data pointer to point to newly allocated memory
  • You are done!

Using the above guidelines; in our case, do the following only if the object is not in an empty state:

  • Create a temp double pointer and allocate memory to the size: m_numCount + 1
  • In a loop, copy all the double m_numbers elements to the double temp number elements (up to m_numCount)
  • Add one to m_numCount (to update the number of double values)
  • copy the value of the double argument to the last element of the double temp array (and therefore add the double value to the list)
  • delete m_numbers to get rid of the original allocated memory
  • Set m_numbers to temp pointer; by doing this m_numbers will point to the newly allocated memory.
  • sort the numbers so the added number stands at the proper location in the array

Regardless of the object being empty or not return the reference of the current object.

display function. (to be implemented)

   ostream& display(ostream& ostr) const

  • if the object is empty, write: "Empty list".
  • if the object is not empty start by writing: "=========================" on ostr and then go to newline
  • if the object is flagged as original, then write the file name otherwise write "*** COPY ***" and then go to new line
  • write all the double numbers separated by ", " (A comma and a space) and then go to new line
  • write "-------------------------" and go to new line
  • Write "Total of " << m_numCount << " number(s)" and go to new line
  • write "Largest number: " and the largest number in the list and go to new line
  • write "Smallest number: " and the smallest number in the list and go to new line
  • write "Average : " and the average of all the numbers inthe list and go to new line
  • write "=========================" and DO NOT GO TO NEWLINE

At the end return the ostr object.

Execution sample

A Numbers object that has the double values 34.1, 3, 6, 12.2 and 34.56 in a file called numbers.txt
should be displayed as follows:

=========================  numbers.txt  3, 6, 12.2, 34.1, 34.56  -------------------------  Total of 5 number(s)  Largest number:  34.56  Smallest number: 3  Average :        17.972  ========================= 

If a Number object is empty, it will be displayed as follows:

Empty list 

Helper function overlaods (to be implemented)

ostream& operator<<(ostream& os, const Numbers& N);

Overload the insertion operator to display the Numbers object using istream.

  • call the display fucntion of N and return it

istream& operator>>(istream& istr, Numbers& N);

Overload the extraction operator to display the Numbers object using istream.

  • read a double value using istr
  • add the double value to N using += operator
  • return istr;

the tester program and the execution sample.

The tester program's execution should generate the following output:

Test 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1  =========================  numbers.txt  3, 6, 12.2, 34.1, 34.56  -------------------------  Total of 5 number(s)  Largest number:  34.56  Smallest number: 3  Average :        17.972  =========================  Add a number to the list: 1000  =========================  *** COPY ***  3, 6, 12.2, 34.1, 34.56, 1000  -------------------------  Total of 6 number(s)  Largest number:  1000  Smallest number: 3  Average :        181.643  =========================  End Test 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1    Content of "numbers.txt"  *****************************************************************  3  6  12.2  34.1  34.56  *****************************************************************  Test 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2  =========================  numbers.txt  3, 6, 12.2, 34.1, 34.56  -------------------------  Total of 5 number(s)  Largest number:  34.56  Smallest number: 3  Average :        17.972  =========================  =========================  *** COPY ***  3, 6, 12.2, 34.1, 34.56  -------------------------  Total of 5 number(s)  Largest number:  34.56  Smallest number: 3  Average :        17.972  =========================  Empty list  Empty list  =========================  numbers.txt  3, 6, 12.2, 34.1, 34.56, 1000  -------------------------  Total of 6 number(s)  Largest number:  1000  Smallest number: 3  Average :        181.643  =========================  =========================  *** COPY ***  3, 6, 12.2, 34.1, 34.56, 1000  -------------------------  Total of 6 number(s)  Largest number:  1000  Smallest number: 3  Average :        181.643  =========================  =========================  *** COPY ***  3, 6, 12.2, 34.1, 34.56, 1000  -------------------------  Total of 6 number(s)  Largest number:  1000  Smallest number: 3  Average :        181.643  =========================  End Test 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2    Content of "numbers.txt"  *****************************************************************  3  6  12.2  34.1  34.56  1000  *****************************************************************  Test 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3    In this test we use your insertion and extraction operators to do  File IO. This makes sure your implementation is done correctly  using the reference of istream and ostream and NOT cin and cout    End Test 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3 3    Content of "numbers.txt"  *****************************************************************  -5  3  6  12.2  34.1  34.56  222.1  333.2  1000  *****************************************************************    Content of "add.txt"  *****************************************************************  -5  222.1  333.2  *****************************************************************    Content of "output.txt"  *****************************************************************  =========================  numbers.txt  -5, 3, 6, 12.2, 34.1, 34.56, 222.1, 333.2, 1000  -------------------------  Total of 9 number(s)  Largest number:  1000  Smallest number: -5  Average :        182.24  =========================  *****************************************************************

 

Files to submit:

Numbers.cpp  Numbers.h  main.cpp

 

main.cpp

#include
#include
#include "Numbers.h"
using namespace sdds;
using namespace std;
void startTest(int n) {
  cout << "Test";
  for (int i = 0; i < 30; i++) cout << " " << n;
  cout << endl;
}
void endTest(int n) {
  cout << "End Test";
  for (int i = 0; i < 28; i++) cout << " " << n;
  cout << endl;
}

void resetFile(const char* fname) {
  ofstream f(fname);
  f << 6 << endl << 12.2 << endl << 3 << endl << 34.1 << endl;
}
void displayFile(const char* fname) {
  ifstream f(fname);
  char ch;
  cout << endl << "Content of \"" << fname << "\"" << endl
     << "*****************************************************************" << endl;
  while (f.get(ch)) {
     cout << ch;
  }
  cout << "*****************************************************************" << endl;
}
void displayList(Numbers N) {
  cout << "Add a number to the list: ";
  cin >> N;
  cout << N << endl;
}
void test1() {
  startTest(1);
  Numbers N("numbers.txt");
  N += 34.56;
  cout << N << endl;
  displayList(N);
  endTest(1);
}
void test2() {
  startTest(2);
  Numbers N("numbers.txt");
  Numbers M(N);
  Numbers L;
  Numbers BAD("BadFileName.txt");
  cout << N << endl << M << endl << L << endl << BAD <  M += 1000;
  L = M;
  N = L;
  cout << N << endl << M << endl << L << endl;
  endTest(2);
}
void test3() {
  startTest(3);
  cout << endl << "In this test we use your insertion and extraction operators to do" << endl
     << "File IO. This makes sure your implementation is done correctly" << endl
     << "using the reference of istream and ostream and NOT cin and cout" << endl << endl;
  ifstream addnum("add.txt");
  ofstream output("output.txt");
  Numbers N("numbers.txt");
  addnum >> N;
  addnum >> N;
  addnum >> N;
  output << N << endl;
  endTest(3);
}
int main() {
  resetFile("numbers.txt");
  test1();
  displayFile("numbers.txt");
  test2();
  displayFile("numbers.txt");
  test3();
  displayFile("numbers.txt");
  displayFile("add.txt");
  displayFile("output.txt");
  return 0;
}

 

 

Numbers.cpp

#define _CRT_SECURE_NO_WARNINGS
#include
#include
#include "Numbers.h"
#include "Numbers.h"  // intentional
using namespace std;
namespace sdds {

 
  Numbers::Numbers() {
     setEmpty();
     m_isOriginal = false;
  }

  Numbers::Numbers(const char* filename) {
     setEmpty();
     m_isOriginal = true;
     setFilename(filename);
     m_numCount = numberCount();
     if (m_numCount == 0 || !load()) {
        delete[] m_numbers;
        delete[] m_filename;
        setEmpty();
        m_isOriginal = false;
     }
     else {
        sort();
     }
  }
  Numbers::~Numbers() {
     save();
     delete[] m_numbers;
     delete[] m_filename;
  }
 
  bool Numbers::isEmpty() const {
     return m_numbers == nullptr;
  }

  void Numbers::setEmpty() {
     m_numbers = nullptr;
     m_filename = nullptr;
     m_numCount = 0;
  }
  void Numbers::setFilename(const char* filename) {
     delete[] m_filename;
     m_filename = new char[strlen(filename) + 1];
     strcpy(m_filename, filename);
  }
  void Numbers::sort() {
     int i, j;
     double temp;
     for (i = m_numCount - 1; i > 0; i--) {
        for (j = 0; j < i; j++) {
           if (m_numbers[j] > m_numbers[j + 1]) {
              temp = m_numbers[j];
              m_numbers[j] = m_numbers[j + 1];
              m_numbers[j + 1] = temp;
           }
        }
     }
  }

  double Numbers::average() const {
     double aver = 0.0;
     if (!isEmpty()) {
        for (int i = 0; i < m_numCount; i++)
           aver += m_numbers[i];
        aver = aver / m_numCount;
     }
     return aver;
  }
  double Numbers::min() const {
     double minVal = 0.0;
     if (!isEmpty()) {
        minVal = m_numbers[0];
        for (int i = 1; i < m_numCount; i++)
           if (minVal > m_numbers[i]) minVal = m_numbers[i];
     }
     return minVal;
  }
  double Numbers::max() const {
     double maxVal = 0.0;
     if (!isEmpty()) {
        maxVal = m_numbers[0];
        for (int i = 1; i < m_numCount; i++)
           if (maxVal < m_numbers[i]) maxVal = m_numbers[i];
     }
     return maxVal;
  }


 
}
 

 

 

Numbers.h

#ifndef SDDS_NUMBERS_H_
#define SDDS_NUMBERS_H_
#include
namespace sdds {
  class Numbers {
     double* m_numbers;
     char* m_filename;
     bool m_isOriginal;
     int m_numCount;
     bool isEmpty()const;
     void setEmpty();
     void setFilename(const char* filename);
     void sort();
  public:
     Numbers();
     Numbers(const char* filename);
     double average()const;
     double max()const;
     double min()const;
     ~Numbers();
  };
}
#endif // !SDDS_NUMBERS_H_

Step by Step Solution

There are 3 Steps involved in it

Step: 1

To complete the implementation of the Numbers class and fulfill the requirements outlined in the provided specifications youll need to implement sever... blur-text-image

Get Instant Access to Expert-Tailored Solutions

See step-by-step solutions with expert insights and AI powered tools for academic success

Step: 2

blur-text-image

Step: 3

blur-text-image

Ace Your Homework with AI

Get the answers you need in no time with our AI-driven, step-by-step assistance

Get Started

Recommended Textbook for

Introduction To Programming In Java An Interdisciplinary Approach

Authors: Robert Sedgewick, Kevin Wayne

2nd Edition

0672337843, 9780672337840

More Books

Students also viewed these Business Communication questions