Guest User

Record Database

a guest
May 13th, 2015
100
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 15.07 KB | None | 0 0
  1. #ifndef Scholarship_h
  2. #define Scholarship_h
  3. #include <cstring>
  4.  /**
  5.  * The Scholarship class holds a c-string up to length 100, and a double,
  6.  * which correspond to the name of a scholarship, and its payout, respectively.
  7.  *
  8.  * @author A. Mackey
  9.  * @version 07.05.15
  10.  */
  11. #define MAX_LENGTH 101
  12. class Scholarship {
  13.     private:
  14.         char name[MAX_LENGTH];  // name of Scholarship
  15.         double payout;          // payout of Scholarship
  16.     public:
  17.         //document these constructors properly
  18.         Scholarship () {}
  19.         Scholarship (char n[], double p) {
  20.             strcpy(name, n);
  21.             payout = p;
  22.         }
  23.         /**
  24.          * Getter function for Scholarship name.
  25.          *
  26.          * @return <code>name</code>
  27.          */
  28.         char* getName();
  29.  
  30.         /**
  31.          * Getter function for Scholarship payout.
  32.          *
  33.          * @return <code>payout</code>
  34.          */
  35.         double getPayout();
  36.  
  37.         /**
  38.          * Setter function for Scholarship name.
  39.          *
  40.          * @param sname     the given name to which <code>name</code> is set.
  41.          * @param n         the length of sname.
  42.          */
  43.         void setName(char sname[], int n);
  44.  
  45.         /**
  46.          * Setter function for Scholarship payout.
  47.          *
  48.          * @param p     the given payout to which <code>payout</code> is set.
  49.          */
  50.         void setPayout(double p);
  51. };
  52.  
  53. char* Scholarship::getName() {
  54.     return name;
  55. }
  56.  
  57. double Scholarship::getPayout() {
  58.     return payout;
  59. }
  60.  
  61. void Scholarship::setName(char sname[], int n) {
  62.     strcpy(name, sname);
  63.     name[n] = '\0';
  64. }
  65.  
  66. void Scholarship::setPayout(double p) {
  67.     payout = p;
  68. }
  69. #endif // Scholarship_h
  70.  
  71.  
  72. /**
  73.  * A program which takes record of given scholarships and stores them in a database.
  74.  * The user selects from a menu of options, each of which allows them to access and
  75.  * utilise the database through a variety of functions.
  76.  *
  77.  * @author A. Mackey
  78.  * @author B. Ginther
  79.  * @author A. Rossi
  80.  * @author A. Westvik
  81.  * @version 12.05.15
  82.  */
  83. #include "Scholarship.h"
  84. #include <cstdlib>
  85. #include <fstream>
  86. #include <iostream>
  87. using namespace std;
  88.  
  89. /*
  90.  * note(s):
  91.  *
  92.  * recommend possibly adding count of spots to be filled by new records in order to
  93.  * cut down on database management of indices
  94.  *
  95.  * additionally, add sort file by name/payout function(s).
  96.  *
  97.  * possibly reference objects instead of passing by value for add/delete functions
  98.  *
  99.  * add data type validation for num values
  100.  */
  101.  
  102. /**
  103.  * Writes <code>n</code> to the given <code>file</code>.
  104.  *
  105.  * @param file      database file containing (n) record(s).
  106.  * @param n         number of records.
  107.  */
  108. void addToFile(fstream& file, int n);
  109. /**
  110.  * Appends a <code>record</code> to the given <code>file</code>.
  111.  *
  112.  * @param file      database file containing (n) record(s).
  113.  * @param record    given Scholarship record object to write to file.
  114.  */
  115. void addToFile(fstream& file, Scholarship record);
  116. /**
  117.  * Allows for the deletion of a <code>record</code> within the database file.
  118.  *
  119.  * @param file      database file containing (n) record(s).
  120.  * @param n         number of records.
  121.  */
  122. void deleteRecord(fstream& file, int& n);
  123. /**
  124.  * Displays all <code>record</code>s held within the database file.
  125.  *
  126.  * @param file      database file containing (n) record(s).
  127.  */
  128. void displayAllRecords(fstream& file, int n);
  129. /**
  130.  * Displays a <code>record</code>.
  131.  *
  132.  * @param record    given Scholarship record object to write to file.
  133.  */
  134. void displayRecord(Scholarship record);
  135. /**
  136.  * Adds records the database from a user-provided file.
  137.  * <p>
  138.  * Sequential access input file structure (by line; repeats until EOF):
  139.  *   Scholarship name
  140.  *   Scholarship payout
  141.  *
  142.  * @param file      database file containing (n) record(s).
  143.  * @param n         number of records.
  144.  */
  145. void fileAddRecord(fstream& file, int& n);
  146. /**
  147.  * Prompts the user to select a number between 1 and <code>n</code>.
  148.  *
  149.  * @param i         index variable.
  150.  * @param n         number of records.
  151.  */
  152. void getIndex(int& i, int n);
  153. /**
  154.  * Gathers input for all fields for a given <code>record</code>.
  155.  *
  156.  * @param record    given Scholarship record object.
  157.  */
  158. void setNameAndPayForRecord(Scholarship& record);
  159. /**
  160.  * Reports a user-based input-error.
  161.  */
  162. void invalidSelection();
  163. /**
  164.  * Prompts user to add a <code>record</code> within the database file.
  165.  *
  166.  * @param file      database file containing (n) record(s).
  167.  */
  168. void manualAddRecord(fstream& file, int& n);
  169. /**
  170.  * This function displays a list of menu options which allow a user access to a
  171.  * database of records.
  172.  *
  173.  * @param file          database file containing (n) record(s).
  174.  * @param countFile     file containing count (n) of records in <code>file</code>.
  175.  */
  176. void menu(fstream& file, fstream& countFile);
  177. /**
  178.  * Prompts user to modify a <code>record</code> within the database file at a
  179.  * user-given index.
  180.  *
  181.  * @param file      database file containing (n) record(s).
  182.  * @param n         number of records.
  183.  */
  184. void modifyRecordAtIndex(fstream& file, int n);
  185. /**
  186.  * Attempts to open necessary files for program operation.
  187.  */
  188. void openAndValidateFiles();
  189. /**
  190.  * Removes a <code>record</code> from the given <code>file</code>.
  191.  *
  192.  * @param file          database file containing (n) record(s).
  193.  * @param record        given Scholarship record object to write to file.
  194.  * @param sizeOfRecord  size of Scholarship object
  195.  * @param i             index of record.
  196.  */
  197. void readRecord(fstream& file, Scholarship& record, int sizeOfRecord, int i);
  198. /**
  199.  * Removes a <code>record</code> from the given <code>file</code>.
  200.  *
  201.  * @param file      database file containing (n) record(s).
  202.  * @param record    given Scholarship record object to write to file.
  203.  * @param n         index of record.
  204.  */
  205. void removeFromFile(fstream& file, Scholarship record, int i);
  206. /**
  207.  * Searches for record(s) within the database file matching user-given fields.
  208.  *
  209.  * @param file      database file containing (n) record(s).
  210.  */
  211. void searchAndDisplayRecordByField(fstream& file, int n);
  212. /**
  213.  * Searches for record within the database file at user-given index.
  214.  *
  215.  * @param file      database file containing (n) record(s).
  216.  * @param n         number of records.
  217.  */
  218. void searchAndDisplayRecordByIndex(fstream& file, int n);
  219.  
  220. int main() {
  221.     openAndValidateFiles();
  222.  
  223.     return 0;
  224. }
  225.  
  226. void addToFile(fstream& file, int n) {
  227.     file.write(reinterpret_cast<char*>(&n), sizeof(int));
  228. }
  229.  
  230. void addToFile(fstream& file, Scholarship record) {
  231.     file.write(reinterpret_cast<char*>(&record), sizeof(Scholarship));
  232. }
  233.  
  234. void deleteRecord(fstream& file, int& n) {
  235.     Scholarship record;
  236.     char chooseDelete;
  237.     int recordNumber;
  238.  
  239.     getIndex(recordNumber, n);
  240.  
  241.     //display record
  242.     if(n > 0) {
  243.         file.seekg((recordNumber-1) * sizeof(record), ios::beg);
  244.         file.read(reinterpret_cast<char*>(&record), sizeof(record));
  245.         displayRecord(record);
  246.  
  247.         //check for deletion confirmation
  248.         cout << "Are you sure you wish to delete this record? [Y/N]: " << endl;
  249.         cin >> chooseDelete;
  250.         chooseDelete = toupper(chooseDelete);
  251.         if(chooseDelete == 'Y') {
  252.             //delete record
  253.             n--;
  254.         }
  255.         cout << endl;
  256.     }
  257. }
  258.  
  259. void displayAllRecords(fstream& file, int n) {
  260.     Scholarship record;
  261.     int recordNumber = 1;
  262.  
  263.     //read and display the records in reverse
  264.     if(n > 0) {
  265.         while(!file.eof()) {
  266.             readRecord(file, record, sizeof(record), recordNumber);
  267.             displayRecord(record);
  268.             recordNumber++;
  269.         }
  270.     } else {
  271.         cout << "There are no records to display." << endl;
  272.     }
  273. }
  274.  
  275. void displayRecord(Scholarship record) {
  276.     cout << "Name: " << record.getName() << endl;
  277.     cout << "Payout: " << record.getPayout() << endl << endl;
  278. }
  279.  
  280. void fileAddRecord(fstream& file, int& n) {
  281.     Scholarship record;             //object holding Scholarship record data
  282.     char val[MAX_LENGTH];           //temporary variable to hold next line of file
  283.     char filename[FILENAME_MAX];    //user filename
  284.     fstream userFile;               //user file
  285.  
  286.     //get user filename and attempt to open file
  287.     cout << "Enter a filename (Ex: file.txt): ";
  288.     cin >> filename;
  289.     userFile.open(filename, ios::in);
  290.  
  291.     //tests if user file exists; if it doesn't, throws error
  292.     if(!userFile) {
  293.         cout << "File not found.";
  294.     }
  295.  
  296.     while(!userFile.eof() && userFile) {
  297.         file.getline(val, MAX_LENGTH-1, '\n'); //get name line from file; set to val
  298.         record.setName(val, strlen(val));      //set name to name stored in val
  299.         file.getline(val, MAX_LENGTH-1, '\n'); //get pay line from file; set to val
  300.         record.setPayout(atof(val));           //set payout to name stored in val
  301.         addToFile(file, record);               //write record into database file
  302.         n++;                                   //increment counter for new record
  303.     }
  304.     cout << endl;
  305. }
  306.  
  307. void getIndex(int& i, int n) {
  308.     bool invalidEntry;
  309.     if(n > 0) {
  310.         do {
  311.             invalidEntry = false;
  312.             cout << "Enter a number [1 to " << n << "]: ";
  313.             cin >> i;
  314.             if(cin.fail()) {
  315.                 invalidEntry = true;    //entry is invalid
  316.                 cin.clear();            //clear stream
  317.                 cin.ignore();           //ignore left over data
  318.                 invalidSelection();     //display error message
  319.             }
  320.         } while((i < 1 || i > n) || invalidEntry);
  321.     } else {
  322.         cout << "There are no records to display." << endl;
  323.     }
  324. }
  325.  
  326. void setNameAndPayForRecord(Scholarship& record) {
  327.     static char name[MAX_LENGTH];
  328.     static double payout;
  329.  
  330.     cout << "Enter name: ";
  331.     cin >> name;
  332.     record.setName(name, strlen(name));
  333.  
  334.     cout << "Enter payout:";
  335.     cin >> payout;
  336.     record.setPayout(payout);
  337. }
  338.  
  339. void invalidSelection() {
  340.     cout << "Invalid entry. Press any key to continue: ";
  341.     cin.get();
  342.     cout << endl;
  343. }
  344.  
  345. void manualAddRecord(fstream& file, int& n) {
  346.     Scholarship record;
  347.  
  348.     setNameAndPayForRecord(record);
  349.     addToFile(file, record);
  350.  
  351.     n++;
  352. }
  353.  
  354. void menu(fstream& file, fstream& countFile) {
  355.     int menuSelection,
  356.         counter;
  357.     char val[MAX_LENGTH];
  358.  
  359.     if(!countFile.eof()) {
  360.         countFile.getline(val, MAX_LENGTH-1, '\n');
  361.         counter = atof(val);
  362.     }
  363.  
  364.     do {
  365.  
  366.         //menu options
  367.         cout << "Select an option from the following:" << endl;
  368.         cout << "[1] Input file name with list of scholarships to add." << endl;
  369.         cout << "[2] Search for record by number [1 to n] and display." << endl;
  370.         cout << "[3] Search for record by one or more fields. Multiple records may be displayed." << endl;
  371.         cout << "[4] Modify record [1 to n] (must enter values for each field)." << endl;
  372.         cout << "[5] Display all records." << endl;
  373.         cout << "[6] Add a record manually." << endl;
  374.         cout << "[7] Delete record [1 to n]." << endl;
  375.         cout << "[0] Quit." << endl;
  376.         cin >> menuSelection;
  377.  
  378.         //corresponding menu actions based on selection
  379.         switch(menuSelection) {
  380.             case 1:
  381.                 fileAddRecord(file, counter);
  382.                 break;
  383.             case 2:
  384.                 searchAndDisplayRecordByIndex(file, counter);
  385.                 break;
  386.             case 3:
  387.                 searchAndDisplayRecordByField(file, counter);
  388.                 break;
  389.             case 4:
  390.                 modifyRecordAtIndex(file, counter);
  391.                 break;
  392.             case 5:
  393.                 displayAllRecords(file, counter);
  394.                 break;
  395.             case 6:
  396.                 manualAddRecord(file, counter);
  397.                 break;
  398.             case 7:
  399.                 deleteRecord(file, counter);
  400.                 break;
  401.             case 0:
  402.                 cout << "You selected Quit. Exiting ... ";
  403.                 break;
  404.             default:
  405.                 invalidSelection();
  406.                 break;
  407.         }
  408.         addToFile(countFile, counter);
  409.         cout << endl;
  410.     } while(menuSelection != 0);
  411. }
  412.  
  413. void modifyRecordAtIndex(fstream& file, int n) {
  414.     Scholarship record;
  415.     int recordNumber;
  416.  
  417.     getIndex(recordNumber, n);
  418.     readRecord(file, record, sizeof(record), recordNumber);
  419.     displayRecord(record);
  420.  
  421.     if(n > 0) {
  422.         setNameAndPayForRecord(record);
  423.         file.seekp(recordNumber * sizeof(record), ios:: beg);
  424.         file.write(reinterpret_cast<const char *>(&record), sizeof(record));
  425.     }
  426. }
  427.  
  428. void openAndValidateFiles() {
  429.     //opens files
  430.     fstream file;
  431.     fstream countFile;
  432.  
  433.     file.open("sappdbase.bin", ios::in|ios::out|ios::app|ios::binary);
  434.     countFile.open("countfile.bin", ios::in|ios::out|ios::app|ios::binary);
  435.  
  436.     //tests if database file exists; if it doesn't, creates the file
  437.     if(!file) {
  438.         file.close();
  439.         file.open("sappdbase.bin", ios::in|ios::out|ios::app|ios::binary);
  440.     }
  441.  
  442.     //tests if count file exists; if it doesn't, creates the file
  443.     if(!countFile) {
  444.         countFile.close();
  445.         countFile.open("countfile.bin", ios::in|ios::out|ios::binary);
  446.         addToFile(countFile, 0);
  447.     }
  448.  
  449.     //continues to the menu if all necessary files are presents; exits otherwise.
  450.     if(file && countFile) {
  451.         menu(file, countFile);
  452.     } else {
  453.         cout << "Failed to locate necessary database file(s). Exiting ...";
  454.     }
  455.  
  456.     file.close();
  457.     countFile.close();
  458. }
  459.  
  460. void readRecord(fstream& file, Scholarship& record, int sizeOfRecord, int i) {
  461.     file.seekg((i-1)*sizeof(record), ios::beg);
  462.     file.read(reinterpret_cast<char *>(&record), sizeof(record));
  463. }
  464.  
  465. void removeFromFile(fstream& file, Scholarship record, int n) {
  466.     //remove <code>record</code> #n from <code>file</code>
  467.     //shift all other records down one?
  468. }
  469.  
  470. void searchAndDisplayRecordByField(fstream& file, int n) {
  471.     bool invalid = false;
  472.     int fieldSelection;
  473.  
  474.     if(n > 0) {
  475.         do {
  476.             cout << "Search by:" << endl;
  477.             cout << "[1] Name." << endl;
  478.             cout << "[2] Payout." << endl;
  479.             cout << "[3] Both." << endl;
  480.             cin >> fieldSelection;
  481.  
  482.             switch(fieldSelection) {
  483.                 case 1:
  484.                     //search by name
  485.                     break;
  486.                 case 2:
  487.                     //search by payout
  488.                     break;
  489.                 case 3:
  490.                     //search by both
  491.                     break;
  492.                 default:
  493.                     invalidSelection();
  494.                     break;
  495.             }
  496.         } while(invalid);
  497.     } else {
  498.         cout << "There are no records to display.";
  499.     }
  500.     cout << endl;
  501. }
  502.  
  503. void searchAndDisplayRecordByIndex(fstream& file, int n) {
  504.     Scholarship record;
  505.     int recordNumber;
  506.  
  507.     getIndex(recordNumber, n);
  508.  
  509.     if(!(recordNumber < 1 || recordNumber > n)) {
  510.         readRecord(file, record, sizeof(record), recordNumber);
  511.         displayRecord(record);
  512.     }
  513. }
Advertisement
Add Comment
Please, Sign In to add comment