Skip to content

Instantly share code, notes, and snippets.

@jnickg
Last active March 25, 2023 08:00
Show Gist options
  • Star 3 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jnickg/6199388 to your computer and use it in GitHub Desktop.
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.
#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;
}
#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;
};
// 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;
}
@uxlsl
Copy link

uxlsl commented Mar 25, 2023

good

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment