Last active
March 25, 2023 08:00
-
-
Save jnickg/6199388 to your computer and use it in GitHub Desktop.
A simple C++ class to demonstrate how to read and write to/from a physical file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <iomanip> | |
#include "filearray.h" | |
using namespace std; | |
// flags for opening a file that already exists | |
static const ios::open_mode readWriteMode = ios::in | ios::out | ios::binary; | |
// flags for creating a file that does not yet exist | |
static const ios::open_mode createMode = ios::out | ios::binary; | |
FileArray::FileArray(char *fileName) : | |
prevIndex(0), | |
prevValue(0), | |
value(0) | |
{ | |
file.open(fileName, createMode); // create file | |
file.close(); // close so we can re-open | |
file.open(fileName, readWriteMode); // open file in read/write mode | |
status = file.is_open() && file.good(); // record stream status | |
} | |
FileArray::~FileArray(void) | |
{ | |
cout << "~FileArray" << endl; | |
cout << *this; | |
// write out previously set value to file if necessary | |
// "the last slice of banana" | |
if (value != prevValue) | |
setValue(prevIndex, value); | |
file.close(); | |
cout << endl << endl; | |
} | |
bool FileArray::getStatus(void) | |
{ | |
return status; | |
} | |
char FileArray::getValue(int index) | |
{ | |
char v; | |
bool eof = false; | |
file.seekg(index * sizeof(v)); | |
file.read((char *) &v, sizeof(v)); | |
if (file.eof()) { | |
file.clear(); // clear eof and fail error bits | |
v = 0; // default value for Windows file system | |
eof = true; | |
} | |
cout << setw(7) << right << (int) v << " <- file[" << index << "]"; | |
if (eof) | |
cout << " (eof)"; | |
cout << endl; | |
return v; | |
} | |
void FileArray::setValue(int index, char value) | |
{ | |
file.seekp(index * sizeof(value)); | |
file.write((char *) &value, sizeof(value)); | |
cout << "file[" << index << "] <- " << (int) value << endl; | |
} | |
// This operator[] works on the lefthand side of an assignment by | |
// storing values from the previous time it was called. This allows | |
// it to discover if it was called on the lefthand side by comparing | |
// the data in the 'value' data member to what it put into 'value' | |
// the previous time. If that has changed, then the previous call | |
// was on the lefthand side and the file needs to be updated. | |
char& FileArray::operator[](int index) | |
{ | |
cout << *this; | |
// write out previously set value to file if necessary | |
if (value != prevValue) | |
setValue(prevIndex, value); | |
value = getValue(index); | |
// record current values for next time | |
prevIndex = index; | |
prevValue = value; | |
cout << endl; | |
return value; | |
} | |
streampos FileArray::fileSize(void) | |
{ | |
file.seekg(0, ios::end); // seek to end of file | |
return file.tellg(); // find out where that is | |
} | |
ostream& operator<<(ostream& out, FileArray& fa) | |
{ | |
streamoff size = fa.fileSize() / sizeof(char); | |
bool first = true; | |
out << "{value " << (int) fa.value | |
<< ", prevValue " << fa.prevValue | |
<< ", prevIndex " << fa.prevIndex | |
<< "}" << endl; | |
return out; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <ostream> | |
#include <fstream> | |
// manages an array of ints that is stored in a file | |
class FileArray | |
{ | |
public: | |
FileArray(char *fileName); // create array based on file with this name | |
~FileArray(void); | |
bool getStatus(void); // true means "good", false means "bad" | |
char getItem(int index); // get item at position specified by index | |
// proper use requires properly invoking the destructor | |
char& operator[](int index); // overload for both get and set | |
friend std::ostream& operator<<(std::ostream& out, FileArray& fa); | |
private: | |
std::fstream file; // stream to/from array file | |
bool status; // file status | |
std::streampos fileSize(void); | |
// enable use of operator[] to set values in array | |
char getValue(int index); // get value from file | |
void setValue(int index, char value); // set item at position specified by index | |
char value; // operator[] returns reference to here | |
// these variables support use of operator[] on the left side of an | |
// assignment statement. | |
// this requires proper invocation of the destructor, to deal with prevIndex | |
int prevIndex; | |
int prevValue; | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// operator[] works for both 'get' and 'set' | |
#include <iostream> | |
#include <iomanip> | |
#include "FileArray.h" | |
using namespace std; | |
int main(int argc, char **argv) | |
{ | |
int x; | |
FileArray fileArray("fileArray3.bin"); // put your filename here | |
if (! fileArray.getStatus()) { | |
cout << "couldn't open file" << endl; | |
return -1; | |
} | |
// set values in file | |
cout << "fileArray[7] = 7" << endl; | |
fileArray[7] = 7; | |
// get item past end of the file | |
cout << "x = fileArray[9]" << endl; | |
x = fileArray[9]; | |
// demonstrate getting item 5 | |
cout << "x = fileArray[5]" << endl; | |
x = fileArray[5]; | |
// demonstrate setting item 5 | |
cout << "fileArray[5] = 5" << endl; | |
fileArray[5] = 5; | |
// demonstrate getting item 5 | |
cout << "x = fileArray[5]" << endl; | |
x = fileArray[5]; | |
// demonstrate getting item 5 | |
cout << "x = fileArray[5]" << endl; | |
x = fileArray[5]; | |
// last use is a set (not a get), to test whether | |
// the value will be written into the file | |
cout << "fileArray[0] = 9" << endl; | |
fileArray[1] = 1; | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
good