Question
Need to complete the implementation of theTextFilemodule. Must run on g++ compiler. This module attaches itself to a text file on the hard drive and
Need to complete the implementation of theTextFilemodule.
Must run on g++ compiler.
This module attaches itself to a text file on the hard drive and loads the content of the text file into an array ofLines.
This module is then capable of displaying the text file page by page on the screen or give the user program read-only access to the lines of the text file as an array of C-strings.
ATextfilecan be safely copied, and the copying will also result in the creation of a copy of the attached file on the hard drive.
ATextFilecan be safely assigned to anotherTextFile, and the assignment will also overwrite the contents of the target file on the hard drive with the content of the source file.
the implementation only needs one class ), theTextFilemodule contains two classes;LineandTextFile.
TheLineclass encapsulates a single line of a text file. TheTextFileencapsulates a text file on the hard drive and it is a dynamic array ofLines. This means an instance ofLineclass should not be able to exist outside of aTextFileclass.
To enforce this, make theLineclass fully private and make theTextFileclass a friend of theLineclass. Doing so, only within the scope of theTextFileclass, aLinecan be instantiated and accessed:
class TextFile; // forward declaration class Line{ // fully private, no public member ........ friend class TextFile; }; class TextFile{ public: ....... };
The Line Class
TheLineclass is fully private and should only be accessible by theTextFileclass.
class Line { char* m_value; Line(); ~Line(); operator const char* ()const; Line& operator=(const char* lineContent); // incomplete... };
Attributes (Member variables)
char* m_value
holds the address of the dynamically allocated Cstring (to hold a line of the text file)
Methods (Member functions)
operator const char* ()const;
Returns the address held in them_valueattribute.
Operator=(const char*) overload
Dynamically allocates memory inm_valueand copies the Cstring pointed bylineContentinto it.
default constructor
Initializes them_valueattribute tonullptr.
destructor
Makes sure all the allocated memory is freed.
Make sureLinecan not be copied or assigned to anotherLine.
The TextFile Class
class TextFile { Line* m_textLines; char* m_filename; unsigned m_noOfLines; unsigned m_pageSize; void setFilename(const char* fname, bool isCopy = false); void setNoOfLines(); void loadText(); void saveAs(const char *fileName)const; void setEmpty(); public: TextFile(unsigned pageSize = 15); TextFile(const char* filename, unsigned pageSize = 15); TextFile(const TextFile&); TextFile& operator=(const TextFile&); ~TextFile(); std::ostream& view(std::ostream& ostr)const; std::istream& getFile(std::istream& istr); operator bool()const; unsigned lines()const; const char* name()const; const char* operator[](unsigned index)const; };
Attributes (Member variables)
TextFilehas four private member variables:
Line* m_textLines;
A pointer to hold the dynamic array ofLines. This attribute should be initialized tonullptr
char* m_filename;
A pointer to hold the dynamic Cstring holding the name of the file. This attribute should be initialized tonullptr
unsigned m_noOfLines;
An unsigned integer to be set to the number of lines in the file.
unsigned m_pageSize;
The page size is the number of lines that should be displayed on the screen before the display is paused. After these lines are displayed, the user must hit enter for the next page to appear.
Private Methods (Member functions)
setEmpty
void setEmpty();
deletes them_textLinesdynamic array and sets is tonullptrdeletes them_filenamedynamic Cstring and sets is tonullptrsetsm_noOfLinesattribute tozero.
setFilename
void setFilename(const char* fname, bool isCopy = false);
If the isCopy argument is false, dynamically allocates a Cstring inm_filenameand copies the content of thefnameargument into it. If the isCopy argument is true, dynamically allocates a Cstring inm_filenameand copies the content of thefnameargument with a prefix of"C_"attached to it.
Example: setFilename("abc.txt"); // sets the m_filename to "abc.txt" setFilename("abc.txt", true); // sets the m_filename to "C_abc.txt"
setNoOfLines
void setNoOfLines();
Counts the number of lines in the file:
Creates a localifstreamobject to open the file with the name held inm_filename. Then it will read the file, character by character, and accumulates the number of newlines in them_noOfLinesattribute.
In the end, it will increasem_noOfLinesby one, just in case, the last line does not have a new line at the end.
If the number of lines is zero, it will delete the m_filename and set it to nullptr. (Setting the TextFile to a safe empty state)
loadText
void loadText();
Loads the text filem_filenameinto the dynamic array of Lines pointed bym_textLines:
If them_filenameis null, this function does nothing.
If them_filenameis not null (TextFileis not in a safe empty state ),loadText()will dynamically allocate an array of Lines pointed bym_textLineswith the size kept in m_noOfLines.
Make surem_textLineis deleted before this to prevent memory leak.
make a local instance ofifstreamusing the file namem_filenameto read the lines of the text file.
Since the length of each line is unknown, read the line using a local C++ string object and thegetlinehelperfunction. (note: this is theHELPERgetlinefunction and not a method of istream).
In a loop reads each line into the string object and then sets them_textLinesarray elements to the values returned by thec_str()method of the string object until the reading fails (end of file reached).
After all the lines are read, make sure to update the value of m_noOfline to the actual number of lines read (This covers the possibility of one extra empty line at the end of the file)
saveAs
void saveAs(const char *fileName)const;
Saves the content of the TextFile under a new name.
Use a local ofstream object to open a new file using the name kept in the argument filename. Then loop through the elements of the m_textLines array and write them in the opened file adding a new line to the end of each line.
Constructors
TextFile(unsigned pageSize = 15);
make an empty TextFile and initializes the m_pageSize attribute using the pageSize argument.
TextFile(const char* filename, unsigned pageSize = 15);
Initializes the m_pageSize attribute using the pageSize argument and all the other attributes to nullptr and zero. Then if the filename is not null, it will set the filename, set the number of Lines and load the Text (using the corresponding private methods.)
Rule of three implementations for classes with resource
Implement The Copy Constructor, Copy assignment and destructor.
Copy Constructor
Initializes the m_pageSize attribute using the m_pageSize of the incoming TextFile object and all the other attributes to nullptr and zero. If the incoming Text object is in a valid State, performs the following tasks to copy the textfile and the content safely:
- Sets the file-name to the name of the incoming TextFile object (isCopy set to true)See setFilename()
- Saves the content of the incoming TextFile under the file name of the current TextFile
- set the number of lines
- loads the Text
Copy Assignment
If the current and the incoming TextFiles are valid it will first delete the current text and then overwrites the current file and data by the content of the incoming TextFile.
- deallocate the dynamic array of Text and sets the pointer to null
- Saves the content of the incoming TextFile under the current filename
- Sets the number of lines
- loads the Text
destructor
Deletes all the dynamic data.
public Methods
lines()
unsigned lines()const;
returns m_noOfLines;
view()
std::ostream& view(std::ostream& ostr)const;
Prints the filename and then the content of the file "m_pageSize" lines at a time.
- print the file name
- underline the file name with '=' character
- loops through the lines and print them one by line
- pauses after printing "m_pageSize" lines and prompts the userHit ENTER to continue...and waits for the user to press enter and repeats until all lines are printed.
The function performs no action if theTextFileis in an empty state.
This function receives and returns an instance of istream and uses the instance for printouts.
getFile()
std::istream& getFile(std::istream& istr);
Receives a filename from istr to set the file name of the TextFile. Then sets the number of lines and loads the Text. When done it will return the istr;
index Operator Overload
const char* operator[](unsigned index)const;
Returns the element in the m_textLine array corresponding to the index argument. If the TextFile is in an empty state, it will return null. If the index exceeds the size of the array it should loop back to the beginning.
For example, if the number of lines is 10, the last index should be 9 and index 10 should return the first element and index 11 should return the second element.
Type conversion overloads:
boolean cast
operator bool()const;
Returns true if the TextFile is not in an empty state and returns false if it is.
constant character pointer cast
const char* name()const;
Returns the filename.
Insertion and extraction helper operator overloads
To print and read on and from istream and ostream overload operator<< and operator>>:
operator<<
ostream& operator<<(ostream& ostr, const TextFile& text);
uses the view() method to print the TextFile
operator>>
istream& operator>>(istream& istr, TextFile& text);
uses the getFile() method to get the file name from console and load the content from the file
Tester program
#include#include #include #include "TextFile.h" using namespace sdds; using namespace std; void FirstTen(TextFile T); void Copy(const string& dest, const string& source); void Dump(const string& filename); int main() { TextFile Empty; TextFile BadFilename("badFilename"); Copy("echoes.txt", "echoesOriginal.txt"); Copy("seamus.txt", "seamusOriginal.txt"); TextFile E; TextFile S("seamus.txt"); cout << "Enter the text file name: "; cin >> E; cout << E << endl; cout << S << endl; FirstTen(E); FirstTen(S); E = S; cout << E << endl; cout << "============================================================" << endl; Dump("echoes.txt"); Dump("seamus.txt"); Dump("C_echoes.txt"); Dump("C_seamus.txt"); cout << "*" << Empty << BadFilename << "*" << endl; return 0; } void FirstTen(TextFile T) { if (T) { cout << ">>> First ten lines of : " << T.name() << endl; for (unsigned i = 0; i < 10; i++) { cout << (i + 1) << ": " << T[i] << endl; } } else { cout << "Nothing to print!" << endl; } cout << endl << "-------------------------------------------------------------" << endl; } void Dump(const string& filename) { cout << "DUMP---------------------------------------------------------" << endl; cout << ">>>" << filename << "<<<" << endl ; ifstream fin(filename.c_str()); char ch; while (fin.get(ch)) cout << ch; cout << endl << "-------------------------------------------------------------" << endl; } void Copy(const string& dest, const string& source) { ifstream fin(source.c_str()); ofstream fout(dest.c_str()); char ch; while (fin.get(ch)) fout << ch; }
TextFile.cpp
#include
#include
#include
#include "TextFile.h"
#include "cstring.h"
using namespace std;
namespace sdds {
Line::operator const char* () const {
return (const char*)m_value;
}
Line& Line::operator=(const char* lineValue) {
delete[] m_value;
m_value = new char[strLen(lineValue) + 1];
strCpy(m_value, lineValue);
return *this;
}
Line::~Line() {
delete[] m_value;
}
}
TextFile.h
#ifndef SDDS_TEXTFILE_H__
#define SDDS_TEXTFILE_H__
#include
namespace sdds {
class Text;
class Line {
char* m_value{ nullptr };
operator const char* ()const;
Line() {}
Line& operator=(const char*);
~Line();
friend class TextFile;
// copy and copy assignment prevention goes here
};
class TextFile {
Line* m_textLines;
char* m_filename;
unsigned m_noOfLines;
unsigned m_pageSize;
void setFilename(const char* fname, bool isCopy = false);
void setNoOfLines();
void loadText();
void saveAs(const char *fileName)const;
void setEmpty();
public:
TextFile(unsigned pageSize = 15);
TextFile(const char* filename, unsigned pageSize = 15);
TextFile(const TextFile&);
TextFile& operator=(const TextFile&);
~TextFile();
std::ostream& view(std::ostream& ostr)const;
std::istream& getFile(std::istream& istr);
operator bool()const;
unsigned lines()const;
const char* name()const;
const char* operator[](unsigned index)const;
};
std::ostream& operator<<(std::ostream& ostr, const TextFile& text);
std::istream& operator>>(std::istream& istr, TextFile& text);
}
#endif // !SDDS_TEXTFILE_H__
ExecutionOutputSample.txt
Enter the text file name: echoes.txt
echoes.txt
==========
Overhead the albatross hangs motionless upon the air
And deep beneath the rolling waves
In labyrinths of coral caves
The echo of a distant time
Comes willowing across the sand
And everything is green and submarine
And no one showed us to the land
And no one knows the wheres or whys
But something stirs and something tries
And starts to climb towards the light
Strangers passing in the street
By chance two separate glances meet
And I am you and what I see is me
Hit ENTER to continue...
And do I take you by the hand?
And lead you through the land?
And help me understand the best I can?
And no one calls us to move on
And no one forces down our eyes
And no one speaks and no one tries
And no one flies around the sun
Cloudless everyday you fall upon my waking eyes
Inviting and inciting me to rise
And through the window in the wall
Come streaming in on sunlight wings
A million bright ambassadors of morning
Hit ENTER to continue...
And no one sings me lullabies
And no one makes me close my eyes
And so I throw the windows wide
And call to you across the sky
seamus.txt
==========
I was in the kitchen
Seamus, that's the dog, was outside
Well, I was in the kitchen
Seamus, my old hound, was outside
Well, the sun sinks slowly
But my old hound just sat right down and cried
>>> First ten lines of : C_echoes.txt
1: Overhead the albatross hangs motionless upon the air
2: And deep beneath the rolling waves
3: In labyrinths of coral caves
4: The echo of a distant time
5: Comes willowing across the sand
6: And everything is green and submarine
7:
8: And no one showed us to the land
9: And no one knows the wheres or whys
10: But something stirs and something tries
-------------------------------------------------------------
>>> First ten lines of : C_seamus.txt
1: I was in the kitchen
2: Seamus, that's the dog, was outside
3: Well, I was in the kitchen
4: Seamus, my old hound, was outside
5: Well, the sun sinks slowly
6: But my old hound just sat right down and cried
7: I was in the kitchen
8: Seamus, that's the dog, was outside
9: Well, I was in the kitchen
10: Seamus, my old hound, was outside
-------------------------------------------------------------
echoes.txt
==========
I was in the kitchen
Seamus, that's the dog, was outside
Well, I was in the kitchen
Seamus, my old hound, was outside
Well, the sun sinks slowly
But my old hound just sat right down and cried
============================================================
DUMP---------------------------------------------------------
>>>echoes.txt<<<
I was in the kitchen
Seamus, that's the dog, was outside
Well, I was in the kitchen
Seamus, my old hound, was outside
Well, the sun sinks slowly
But my old hound just sat right down and cried
-------------------------------------------------------------
DUMP---------------------------------------------------------
>>>seamus.txt<<<
I was in the kitchen
Seamus, that's the dog, was outside
Well, I was in the kitchen
Seamus, my old hound, was outside
Well, the sun sinks slowly
But my old hound just sat right down and cried
-------------------------------------------------------------
DUMP---------------------------------------------------------
>>>C_echoes.txt<<<
Overhead the albatross hangs motionless upon the air
And deep beneath the rolling waves
In labyrinths of coral caves
The echo of a distant time
Comes willowing across the sand
And everything is green and submarine
And no one showed us to the land
And no one knows the wheres or whys
But something stirs and something tries
And starts to climb towards the light
Strangers passing in the street
By chance two separate glances meet
And I am you and what I see is me
And do I take you by the hand?
And lead you through the land?
And help me understand the best I can?
And no one calls us to move on
And no one forces down our eyes
And no one speaks and no one tries
And no one flies around the sun
Cloudless everyday you fall upon my waking eyes
Inviting and inciting me to rise
And through the window in the wall
Come streaming in on sunlight wings
A million bright ambassadors of morning
And no one sings me lullabies
And no one makes me close my eyes
And so I throw the windows wide
And call to you across the sky
-------------------------------------------------------------
DUMP---------------------------------------------------------
>>>C_seamus.txt<<<
I was in the kitchen
Seamus, that's the dog, was outside
Well, I was in the kitchen
Seamus, my old hound, was outside
Well, the sun sinks slowly
But my old hound just sat right down and cried
-------------------------------------------------------------
**
Step by Step Solution
There are 3 Steps involved in it
Step: 1
Get Instant Access to Expert-Tailored Solutions
See step-by-step solutions with expert insights and AI powered tools for academic success
Step: 2
Step: 3
Ace Your Homework with AI
Get the answers you need in no time with our AI-driven, step-by-step assistance
Get Started