Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef Scholarship_h
- #define Scholarship_h
- #include <cstring>
- /**
- * The Scholarship class holds a c-string up to length 100, and a double,
- * which correspond to the name of a scholarship, and its payout, respectively.
- *
- * @author A. Mackey
- * @version 07.05.15
- */
- #define MAX_LENGTH 101
- class Scholarship {
- private:
- char name[MAX_LENGTH]; // name of Scholarship
- double payout; // payout of Scholarship
- public:
- //document these constructors properly
- Scholarship () {}
- Scholarship (char n[], double p) {
- strcpy(name, n);
- payout = p;
- }
- /**
- * Getter function for Scholarship name.
- *
- * @return <code>name</code>
- */
- char* getName();
- /**
- * Getter function for Scholarship payout.
- *
- * @return <code>payout</code>
- */
- double getPayout();
- /**
- * Setter function for Scholarship name.
- *
- * @param sname the given name to which <code>name</code> is set.
- * @param n the length of sname.
- */
- void setName(char sname[], int n);
- /**
- * Setter function for Scholarship payout.
- *
- * @param p the given payout to which <code>payout</code> is set.
- */
- void setPayout(double p);
- };
- char* Scholarship::getName() {
- return name;
- }
- double Scholarship::getPayout() {
- return payout;
- }
- void Scholarship::setName(char sname[], int n) {
- strcpy(name, sname);
- name[n] = '\0';
- }
- void Scholarship::setPayout(double p) {
- payout = p;
- }
- #endif // Scholarship_h
- /**
- * A program which takes record of given scholarships and stores them in a database.
- * The user selects from a menu of options, each of which allows them to access and
- * utilise the database through a variety of functions.
- *
- * @author A. Mackey
- * @author B. Ginther
- * @author A. Rossi
- * @author A. Westvik
- * @version 12.05.15
- */
- #include "Scholarship.h"
- #include <cstdlib>
- #include <fstream>
- #include <iostream>
- using namespace std;
- /*
- * note(s):
- *
- * recommend possibly adding count of spots to be filled by new records in order to
- * cut down on database management of indices
- *
- * additionally, add sort file by name/payout function(s).
- *
- * possibly reference objects instead of passing by value for add/delete functions
- *
- * add data type validation for num values
- */
- /**
- * Writes <code>n</code> to the given <code>file</code>.
- *
- * @param file database file containing (n) record(s).
- * @param n number of records.
- */
- void addToFile(fstream& file, int n);
- /**
- * Appends a <code>record</code> to the given <code>file</code>.
- *
- * @param file database file containing (n) record(s).
- * @param record given Scholarship record object to write to file.
- */
- void addToFile(fstream& file, Scholarship record);
- /**
- * Allows for the deletion of a <code>record</code> within the database file.
- *
- * @param file database file containing (n) record(s).
- * @param n number of records.
- */
- void deleteRecord(fstream& file, int& n);
- /**
- * Displays all <code>record</code>s held within the database file.
- *
- * @param file database file containing (n) record(s).
- */
- void displayAllRecords(fstream& file, int n);
- /**
- * Displays a <code>record</code>.
- *
- * @param record given Scholarship record object to write to file.
- */
- void displayRecord(Scholarship record);
- /**
- * Adds records the database from a user-provided file.
- * <p>
- * Sequential access input file structure (by line; repeats until EOF):
- * Scholarship name
- * Scholarship payout
- *
- * @param file database file containing (n) record(s).
- * @param n number of records.
- */
- void fileAddRecord(fstream& file, int& n);
- /**
- * Prompts the user to select a number between 1 and <code>n</code>.
- *
- * @param i index variable.
- * @param n number of records.
- */
- void getIndex(int& i, int n);
- /**
- * Gathers input for all fields for a given <code>record</code>.
- *
- * @param record given Scholarship record object.
- */
- void setNameAndPayForRecord(Scholarship& record);
- /**
- * Reports a user-based input-error.
- */
- void invalidSelection();
- /**
- * Prompts user to add a <code>record</code> within the database file.
- *
- * @param file database file containing (n) record(s).
- */
- void manualAddRecord(fstream& file, int& n);
- /**
- * This function displays a list of menu options which allow a user access to a
- * database of records.
- *
- * @param file database file containing (n) record(s).
- * @param countFile file containing count (n) of records in <code>file</code>.
- */
- void menu(fstream& file, fstream& countFile);
- /**
- * Prompts user to modify a <code>record</code> within the database file at a
- * user-given index.
- *
- * @param file database file containing (n) record(s).
- * @param n number of records.
- */
- void modifyRecordAtIndex(fstream& file, int n);
- /**
- * Attempts to open necessary files for program operation.
- */
- void openAndValidateFiles();
- /**
- * Removes a <code>record</code> from the given <code>file</code>.
- *
- * @param file database file containing (n) record(s).
- * @param record given Scholarship record object to write to file.
- * @param sizeOfRecord size of Scholarship object
- * @param i index of record.
- */
- void readRecord(fstream& file, Scholarship& record, int sizeOfRecord, int i);
- /**
- * Removes a <code>record</code> from the given <code>file</code>.
- *
- * @param file database file containing (n) record(s).
- * @param record given Scholarship record object to write to file.
- * @param n index of record.
- */
- void removeFromFile(fstream& file, Scholarship record, int i);
- /**
- * Searches for record(s) within the database file matching user-given fields.
- *
- * @param file database file containing (n) record(s).
- */
- void searchAndDisplayRecordByField(fstream& file, int n);
- /**
- * Searches for record within the database file at user-given index.
- *
- * @param file database file containing (n) record(s).
- * @param n number of records.
- */
- void searchAndDisplayRecordByIndex(fstream& file, int n);
- int main() {
- openAndValidateFiles();
- return 0;
- }
- void addToFile(fstream& file, int n) {
- file.write(reinterpret_cast<char*>(&n), sizeof(int));
- }
- void addToFile(fstream& file, Scholarship record) {
- file.write(reinterpret_cast<char*>(&record), sizeof(Scholarship));
- }
- void deleteRecord(fstream& file, int& n) {
- Scholarship record;
- char chooseDelete;
- int recordNumber;
- getIndex(recordNumber, n);
- //display record
- if(n > 0) {
- file.seekg((recordNumber-1) * sizeof(record), ios::beg);
- file.read(reinterpret_cast<char*>(&record), sizeof(record));
- displayRecord(record);
- //check for deletion confirmation
- cout << "Are you sure you wish to delete this record? [Y/N]: " << endl;
- cin >> chooseDelete;
- chooseDelete = toupper(chooseDelete);
- if(chooseDelete == 'Y') {
- //delete record
- n--;
- }
- cout << endl;
- }
- }
- void displayAllRecords(fstream& file, int n) {
- Scholarship record;
- int recordNumber = 1;
- //read and display the records in reverse
- if(n > 0) {
- while(!file.eof()) {
- readRecord(file, record, sizeof(record), recordNumber);
- displayRecord(record);
- recordNumber++;
- }
- } else {
- cout << "There are no records to display." << endl;
- }
- }
- void displayRecord(Scholarship record) {
- cout << "Name: " << record.getName() << endl;
- cout << "Payout: " << record.getPayout() << endl << endl;
- }
- void fileAddRecord(fstream& file, int& n) {
- Scholarship record; //object holding Scholarship record data
- char val[MAX_LENGTH]; //temporary variable to hold next line of file
- char filename[FILENAME_MAX]; //user filename
- fstream userFile; //user file
- //get user filename and attempt to open file
- cout << "Enter a filename (Ex: file.txt): ";
- cin >> filename;
- userFile.open(filename, ios::in);
- //tests if user file exists; if it doesn't, throws error
- if(!userFile) {
- cout << "File not found.";
- }
- while(!userFile.eof() && userFile) {
- file.getline(val, MAX_LENGTH-1, '\n'); //get name line from file; set to val
- record.setName(val, strlen(val)); //set name to name stored in val
- file.getline(val, MAX_LENGTH-1, '\n'); //get pay line from file; set to val
- record.setPayout(atof(val)); //set payout to name stored in val
- addToFile(file, record); //write record into database file
- n++; //increment counter for new record
- }
- cout << endl;
- }
- void getIndex(int& i, int n) {
- bool invalidEntry;
- if(n > 0) {
- do {
- invalidEntry = false;
- cout << "Enter a number [1 to " << n << "]: ";
- cin >> i;
- if(cin.fail()) {
- invalidEntry = true; //entry is invalid
- cin.clear(); //clear stream
- cin.ignore(); //ignore left over data
- invalidSelection(); //display error message
- }
- } while((i < 1 || i > n) || invalidEntry);
- } else {
- cout << "There are no records to display." << endl;
- }
- }
- void setNameAndPayForRecord(Scholarship& record) {
- static char name[MAX_LENGTH];
- static double payout;
- cout << "Enter name: ";
- cin >> name;
- record.setName(name, strlen(name));
- cout << "Enter payout:";
- cin >> payout;
- record.setPayout(payout);
- }
- void invalidSelection() {
- cout << "Invalid entry. Press any key to continue: ";
- cin.get();
- cout << endl;
- }
- void manualAddRecord(fstream& file, int& n) {
- Scholarship record;
- setNameAndPayForRecord(record);
- addToFile(file, record);
- n++;
- }
- void menu(fstream& file, fstream& countFile) {
- int menuSelection,
- counter;
- char val[MAX_LENGTH];
- if(!countFile.eof()) {
- countFile.getline(val, MAX_LENGTH-1, '\n');
- counter = atof(val);
- }
- do {
- //menu options
- cout << "Select an option from the following:" << endl;
- cout << "[1] Input file name with list of scholarships to add." << endl;
- cout << "[2] Search for record by number [1 to n] and display." << endl;
- cout << "[3] Search for record by one or more fields. Multiple records may be displayed." << endl;
- cout << "[4] Modify record [1 to n] (must enter values for each field)." << endl;
- cout << "[5] Display all records." << endl;
- cout << "[6] Add a record manually." << endl;
- cout << "[7] Delete record [1 to n]." << endl;
- cout << "[0] Quit." << endl;
- cin >> menuSelection;
- //corresponding menu actions based on selection
- switch(menuSelection) {
- case 1:
- fileAddRecord(file, counter);
- break;
- case 2:
- searchAndDisplayRecordByIndex(file, counter);
- break;
- case 3:
- searchAndDisplayRecordByField(file, counter);
- break;
- case 4:
- modifyRecordAtIndex(file, counter);
- break;
- case 5:
- displayAllRecords(file, counter);
- break;
- case 6:
- manualAddRecord(file, counter);
- break;
- case 7:
- deleteRecord(file, counter);
- break;
- case 0:
- cout << "You selected Quit. Exiting ... ";
- break;
- default:
- invalidSelection();
- break;
- }
- addToFile(countFile, counter);
- cout << endl;
- } while(menuSelection != 0);
- }
- void modifyRecordAtIndex(fstream& file, int n) {
- Scholarship record;
- int recordNumber;
- getIndex(recordNumber, n);
- readRecord(file, record, sizeof(record), recordNumber);
- displayRecord(record);
- if(n > 0) {
- setNameAndPayForRecord(record);
- file.seekp(recordNumber * sizeof(record), ios:: beg);
- file.write(reinterpret_cast<const char *>(&record), sizeof(record));
- }
- }
- void openAndValidateFiles() {
- //opens files
- fstream file;
- fstream countFile;
- file.open("sappdbase.bin", ios::in|ios::out|ios::app|ios::binary);
- countFile.open("countfile.bin", ios::in|ios::out|ios::app|ios::binary);
- //tests if database file exists; if it doesn't, creates the file
- if(!file) {
- file.close();
- file.open("sappdbase.bin", ios::in|ios::out|ios::app|ios::binary);
- }
- //tests if count file exists; if it doesn't, creates the file
- if(!countFile) {
- countFile.close();
- countFile.open("countfile.bin", ios::in|ios::out|ios::binary);
- addToFile(countFile, 0);
- }
- //continues to the menu if all necessary files are presents; exits otherwise.
- if(file && countFile) {
- menu(file, countFile);
- } else {
- cout << "Failed to locate necessary database file(s). Exiting ...";
- }
- file.close();
- countFile.close();
- }
- void readRecord(fstream& file, Scholarship& record, int sizeOfRecord, int i) {
- file.seekg((i-1)*sizeof(record), ios::beg);
- file.read(reinterpret_cast<char *>(&record), sizeof(record));
- }
- void removeFromFile(fstream& file, Scholarship record, int n) {
- //remove <code>record</code> #n from <code>file</code>
- //shift all other records down one?
- }
- void searchAndDisplayRecordByField(fstream& file, int n) {
- bool invalid = false;
- int fieldSelection;
- if(n > 0) {
- do {
- cout << "Search by:" << endl;
- cout << "[1] Name." << endl;
- cout << "[2] Payout." << endl;
- cout << "[3] Both." << endl;
- cin >> fieldSelection;
- switch(fieldSelection) {
- case 1:
- //search by name
- break;
- case 2:
- //search by payout
- break;
- case 3:
- //search by both
- break;
- default:
- invalidSelection();
- break;
- }
- } while(invalid);
- } else {
- cout << "There are no records to display.";
- }
- cout << endl;
- }
- void searchAndDisplayRecordByIndex(fstream& file, int n) {
- Scholarship record;
- int recordNumber;
- getIndex(recordNumber, n);
- if(!(recordNumber < 1 || recordNumber > n)) {
- readRecord(file, record, sizeof(record), recordNumber);
- displayRecord(record);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment