/* Programmer: Assignment: project 9 c++ Purpose: Date: */ #include #include // For I/O #include // For setw() #include // For system() #include // For stricmp() #include "sort.h" // Generic sort() function using namespace std; const int MAX_FILE_NAME = 35; // Maximum file name length const int MAX_ID_LEN = 15; const int MAX_NAME_LEN = 20; const int RATE_CHANGE_POINT = 10; const double RATE1 = 0.10; const double RATE2 = 0.0; class SalesRecord { private: char emp_id[MAX_ID_LEN + 1]; char emp_name[MAX_NAME_LEN +1]; int quantity_sold; double commission_rate; //double commission; double reg_price; double paid_price; double total; public: // Functions that operate on an individual record SalesRecord(); // Default constructor void read(ifstream& in); // Read record from input stream void calc_paid_price(); void calc_total(); void write(ostream & os) const; // Write record to output stream bool operator<(const SalesRecord& right) const;// Overloaded for use in sort }; typedef SalesRecord * SalesRecord_Array; // Used to allocate 1-D sales record array // Utility functions - functions are not specific to this problem void open_input(ifstream& input, char name[]); // Get file name & Open file void open_output(ofstream& output, char name[]); // Get file name & Open file // Funcions that operate on array (set) of records SalesRecord_Array read_records(ifstream& in, int &n); // Allocate space for records & read them void calc_records(SalesRecord_Array records, int n); // Calculate commission rate and commission void write_records(SalesRecord_Array records, int n); // Save records to file int main() // Parameters: None // Returns: Zero // Calls: open_input(), read_records(), calc_commissions(), sort(), write_records(). { char again; int num_records; char infilename[MAX_FILE_NAME + 1]; ifstream in; SalesRecord_Array records = NULL; do { open_input(in, infilename); // Get file name & open file records = read_records(in, num_records); // Read records & get number of records in.close(); // Close file if (records != NULL && num_records > 0) { calc_records(records, num_records); // Calculate commission values for each record sort(records, num_records); // Sort records by employee name write_records(records, num_records); // Save records to new file delete [] records; // Free array of records } else { cout << "\n\n\aNo data in file: " << infilename << endl; } cout << "\nDo you want to process another file (Y/N)? "; cin >> again; cin.ignore(256, '\n'); // Remove Enter key from keyboard buffer } while ( again == 'y' || again == 'Y'); cout << "\n\n***** END OF PROGRAM ******\n";// Print closing message. return 0; } // End of main() // Utility functions void open_input(ifstream& input, char name[]) //Open file // Parameters: Variables for input file reference nad input file name // Returns: None // Calls: None { int count = 0; // Count number of tries do // Continue until we get a valid file name and can open file { count++; if (count != 1) // Issue error message if we are trying again. { cout << "\n\aInvalid file name or file does not exist. Please try again." << endl; } cout << "\nEnter the input file name (maximum of " << MAX_FILE_NAME << " characters please)\n:> "; cin.get(name, MAX_FILE_NAME + 1);// Gets at most MAX_FILE_NAME characters cin.ignore(256, '\n'); // Remove Enter key from keyboard buffer input.clear(); // Clear all error flags, if any, from prev try input.open(name, ios_base::in); // Open only if file exists } while (input.fail() ); // If can't open file, try again } // End of open_input() void open_output(ofstream& output, char name[]) //Open file // Parameters: Variables for output file reference and output file name // Returns: None // Calls: None { int count = 0; // Count number of tries do // Continue until we get a valid file name and can open file { count++; if (count != 1) // Issue error message if we are trying again. { cout << "\n\aInvalid file name. Please try again." << endl; } cout << "\nEnter the output file name (maximum of " << MAX_FILE_NAME << " characters please)\n:> "; cin.get(name, MAX_FILE_NAME + 1);// Gets at most MAX_FILE_NAME characters cin.ignore(256, '\n'); // Remove Enter key from keyboard buffer output.clear(); // Clear all error flags, if any, from prev try output.open(name); // Open file for output } while (output.fail() ); // If can't open file, try again } // End of open_output() // Functions that operate on individual records SalesRecord::SalesRecord() // Initialize data // Parameters: None // Returns: none // Calls: None { emp_id[0] = emp_name[0] ='\0'; // Set strings to null quantity_sold = 0; // Set numeric data to zero commission_rate= 0.0; paid_price = reg_price = total = 0.0; } // End of SalesRecord::SalesRecord() void SalesRecord::read(ifstream& in) // Read record from input stream, does not read commission values // Parameters: Input stream // Returns: none // Calls: None { in.get(emp_id, MAX_ID_LEN +1); // Read id while (in.get() != '\n'); // Clear Enter after id in.get(emp_name, MAX_NAME_LEN +1); // Read name: Last, First while (in.get() != '\n'); // Clear Enter after name in >> quantity_sold >> reg_price; // Read quantity sold value while (in.get() != '\n'); // Clear Enter at end of record } // End of SalesRecord::read() void SalesRecord::calc_paid_price() // Calculate commission fields in record // Parameters: None // Returns: None // Calls: None { if (quantity_sold >= RATE_CHANGE_POINT) commission_rate = RATE1; else commission_rate = RATE2; paid_price = reg_price - (commission_rate * reg_price); } // End of SalesRecord::calc_commission() void SalesRecord::calc_total() { calc_paid_price(); total = quantity_sold * paid_price; } void SalesRecord::write(ostream & os) const// Write record to output stream // Parameters: Output stream, record to be written // Returns : None. // Calls : None. { os.setf(ios::fixed); os.setf(ios::showpoint); os.precision(2); os << emp_id << "\n" << emp_name << "\n" << quantity_sold << " " << total << endl; } // End of SalesRecord::write() bool SalesRecord::operator<(const SalesRecord& right) const// Overloaded for use in sort // Parameters: Record to be compared - on right side of < operator // Returns: true if emp_name in first record < emp_name in second record, false otherwise // Calls: None { if (strcmp(emp_name, right.emp_name) < 0) return true; else return false; } // End of SalesRecord::operator< // Funcions that operate on array (set) of records SalesRecord_Array read_records(ifstream& in, int &n) // Allocate space for records & read them // Parameters: Input stream, variable for number of records. // Returns : Pointer to array of records allocated. // Calls : SalesRecord::read(). { in >> n; // Read number of records if (n < 1 || in.fail()) return NULL; // No records to read return while (in.get() != '\n'); // Clear enter after number of records in file SalesRecord_Array records; // Pointer for array of records records = new SalesRecord[n]; // allocate space for records if (records == NULL) { cout << "\aCan not allocate memory!"; exit(1); } int i; for(i = 0; in.good() && !in.eof() && i < n; i++) { records[i].read(in); // Read each record } return records; // Return pointer to array } // End of read_records() void calc_records(SalesRecord_Array records, int n) // Calculate commission rate and commission // Parameters: Array of records, number of records. // Returns : None. // Calls : SalesRecord::calc_commission(). { int i; for(i = 0; i < n; i++) { records[i].calc_total(); // Process each record } } // End of calc_records() void write_records(SalesRecord_Array records, int n) // Save records to file // Parameters: Array of records, number of records. // Returns : None. // Calls : SalesRecord::write(). { char outfilename[MAX_FILE_NAME + 1]; // Name of file for output records ofstream out; // Output file stream cout << "\n\nI need the output file name." << endl; open_output(out, outfilename); // Get file name & open file if (out.good()) { out << n << endl; // Write number of records to file int i; for(i = 0; i < n; i++) { records[i].write(out); // Write each record to file } out.close(); } else { cout << "\a\nUnable to save data!" << endl; } } // End of write_records()