//Code by Jordan Harris-Toovy for OIT's CST116-01P lab 9, December 2021 #include #include #include #include #include #include using namespace std; #define MV_1 10 #define MV_3 30 //16a - 11.14 Programming Exercises #2: /* void bubiSort(int[MV_1], int); int loadFileData(ifstream&, int[MV_1]); int main(void) { string path = "C:\\Users\\jorda\\source\\repos\\cst116-lab9-JordanHT-OIT\\CST116F2021-Lab9\\", fileName, ext = ".txt"; ifstream dataFile; int length = 0, data[MV_1]; bool fileValid = false; do //Ask the user for the file name until a valid filename is entered { cout << "Enter name of data file: "; getline(cin, fileName); dataFile.open(path + fileName + ext); fileValid = !dataFile.fail(); if (!fileValid) { cout << "Invalid file name" << endl; } } while (!fileValid); length = loadFileData(dataFile, data); dataFile.close(); bubiSort(data, length); //Sort the array in assending order cout << "The smallest number in the file is: " << data[0] << "\nThe largest number in the file is: " << data[length - 1] << endl; cout << "The file contents are: " << endl; for (int idx = 0; idx < length; idx++) //Print all of the data { cout << data[idx] << " "; } cout << endl; return (0); } //Load an array with data from a filestream int loadFileData(ifstream& inData, int arr[MV_1]) { int entries = 0; while (!inData.eof()) { inData >> arr[entries]; entries++; } return (--entries); } //My poor implementation of bubblesort void bubiSort(int arr[MV_1], int len) { int pass = 0, hold = 0; while (pass <= len) { for (int idx = 0; idx < (len - 1); idx++) { if (arr[idx] > arr[idx + 1]) { hold = arr[idx + 1]; arr[idx + 1] = arr[idx]; arr[idx] = hold; pass = 0; } else { pass++; } } } } */ //16a - 11.14 Programming Exercises #3: /* int main(void) { string path = "C:\\Users\\jorda\\source\\repos\\cst116-lab9-JordanHT-OIT\\CST116F2021-Lab9\\", fileName, ext = ".txt", currentLine; ifstream dataFile; bool fileFailed = false; int lineNumber = 0; do //Ask the user for the file name until a valid filename is entered { cout << "Enter name of data file: "; getline(cin, fileName); dataFile.open(path + fileName + ext); fileFailed = dataFile.fail(); if (fileFailed) { cout << "Invalid file name" << endl; } } while (fileFailed); cout << endl; while (!dataFile.eof()) //Repeat until EOF { getline(dataFile, currentLine); cout << 1 + lineNumber++ << ")\t" << currentLine << "\t(" << currentLine.length() << " chars)" << endl; //Use the .length class to display the number of chars } dataFile.close(); return (0); } */ //16a - 11.14 Programming Exercises #4: //Known issue: The code only indexes by the fist letter of the last names, so within the names of the same fist letter, their order will be as entered. bool getInt(int&); int indexFistChar(string); void bubiSortIndex(int[MV_3], int[MV_3], int); void swapDataArray(string[4][MV_3], int[MV_3], int&); void populateMetaData(int[2][MV_3], string[4][MV_3], int); bool populateDataArray(string, string[4][MV_3], int&); int findPerson(string[4][MV_3], int); void displayEntry(string[4][MV_3], int); int main(void) { int menuChoice = 0, numEntries = 0, metaData[2][MV_3]{ 0 }, select = 0; string fileLoc = "C:\\Users\\jorda\\source\\repos\\cst116-lab9-JordanHT-OIT\\CST116F2021-Lab9\\1114_4_datafile.txt"; //Hardcoded file path because flexibility was not required string mainData[4][MV_3]; if (!populateDataArray(fileLoc, mainData, numEntries)) { return (1); } populateMetaData(metaData, mainData, numEntries); //Make fist map bubiSortIndex(metaData[0], metaData[1], numEntries); cout << "Personnel manifest explorer MK1" << endl; do { cout << "Enter desired operation:\n" << "1)\tPersonnel lookup\n" << "2)\tAdd entry\n" << "3)\tEdit entry\n" << "4)\tDisplay all records\n" << "5)\tExit program" << endl; while (!getInt(menuChoice) || (menuChoice > 5) || (menuChoice < 1)) //Get menu choice from user { cout << "Invalid input; enter again: "; } switch (menuChoice) { case(1): //Find personnel infomation by first name and last name, or by phone number select = findPerson(mainData, numEntries); cout << endl; if (select < 0) //Break out if a match was not found or the user quit { break; } displayEntry(mainData, select); cout << endl << endl; break; case(2): //Add a person to the database cout << "Enter the first name: "; cin >> mainData[0][++numEntries]; cout << "Enter the last name: "; cin >> mainData[1][numEntries]; cout << "Enter the phone number (format: 012-345-6789): "; cin >> mainData[2][numEntries]; cout << "Enter the date of birth (format: yyyy-mm-dd): "; cin >> mainData[3][numEntries]; cout << endl; break; case(3): //Edit personnel infomation. Uses same logic as case 1 to find the entry to edit cout << "Enter 1 if index is known, or 2 to find a person: "; while (!getInt(menuChoice) || (menuChoice > 2) || (menuChoice < 1)) { cout << "Invalid input; enter again: "; } if (menuChoice == 1) //Direct index imput { cout << "Enter index: "; if (!getInt(select)) { cout << "Invalid index"; } } else //Lookup if the user does not know the index of the entry { select = findPerson(mainData, numEntries); } do //Let the user change any amount of params until they exit { cout << "Select element to change:\n1)\tFirst name\n2)\tLast name\n3)\tPhone number\n4)\tDate of birth\n5)\tExit\n"; while (!getInt(menuChoice) || (menuChoice > 5) || (menuChoice < 1)) { cout << "Invalid input; enter again: "; } switch (menuChoice) { case(1): cout << "Enter the first name: "; cin >> mainData[0][select]; break; case(2): cout << "Enter the last name: "; cin >> mainData[1][select]; break; case(3): cout << "Enter the phone number (format: 012-345-6789): "; cin >> mainData[2][select]; break; case(4): cout << "Enter the date of birth (format: yyyy-mm-dd): "; cin >> mainData[3][select]; break; } } while (menuChoice != 5); menuChoice = -1; //Reset menu value to avoid program exit break; case(4): //Displays all available information using metaData as a map cout << left; cout << endl << setw(25) << "First name" << setw(25) << "Last name" << setw(25) << "Phone number" << setw(25) << "Date of birth" << endl; for (int idx = 0; idx < (25 * 4); idx++) { cout << char(205); } cout << endl; for (int idx = 0; idx <= numEntries; idx++) { displayEntry(mainData, metaData[0][idx]); cout << endl; } cout << endl; break; } populateMetaData(metaData, mainData, numEntries); //Regenerate map bubiSortIndex(metaData[0], metaData[1], numEntries); } while (menuChoice != 5); return (0); } //Returns the ASCII value for the fist char (always as uperace) in the input string int indexFistChar(string inputString) { inputString[0] = toupper(inputString[0]); //Ensure the fist char of the string is uppercase return((int)inputString[0]); } //Sorts an input array and creates a map of the changes (swap locations) for len number of entries void bubiSortIndex(int map[MV_3], int dataArray[MV_3], int len) { int pass = 0, hold = 0; while (pass <= len) { for (int idx = 0; idx < (len); idx++) { if (dataArray[idx] > dataArray[idx + 1]) { hold = dataArray[idx + 1]; dataArray[idx + 1] = dataArray[idx]; dataArray[idx] = hold; hold = map[idx + 1]; map[idx + 1] = map[idx]; map[idx] = hold; pass = 0; } else { pass++; } } } } //Swaps the dataArray using a map for a specified number of entries (UNUSED) void swapDataArray(string dataArray[4][MV_3], int meta[MV_3], int &entries) { string swapValue[4]; for (int idx = 0; idx < entries; idx++) { if (meta[idx] > 0) { for (int idy = 0; idy < 4; idy++) { swapValue[idy] = dataArray[idy][idx]; dataArray[idy][idx] = dataArray[idy][meta[idx]]; dataArray[idy][meta[idx]] = swapValue[idy]; } } } } //Fills a metadata array with position data and ASCII values of the first char (made upercase) of the last names void populateMetaData(int meta[2][MV_3], string dataAray[4][MV_3], int entries) { for (int idx = 0; idx <= entries; idx++) { meta[0][idx] = idx; meta[1][idx] = indexFistChar(dataAray[1][idx]); } } //Opens a file at the provied path, the enters its contents into an array. Returns false if there is an I/O error bool populateDataArray(string fileLoc, string dataArray[4][MV_3], int& numEntries) { ifstream inputFile; bool isFileOpen = false; int index = 0; inputFile.open(fileLoc); //Open datafile and check if opening was successful. If not, diplay error and exit isFileOpen = !inputFile.fail(); if (!isFileOpen) { cout << "File read error: Cannot open" << endl; return (isFileOpen); } else { isFileOpen = true; } inputFile >> dataArray[0][index] >> dataArray[1][index] >> dataArray[2][index] >> dataArray[3][index]; //Priming read numEntries = 1; while (!inputFile.eof()) { index++; inputFile >> dataArray[0][index] >> dataArray[1][index] >> dataArray[2][index] >> dataArray[3][index]; numEntries++; } numEntries--; inputFile.close(); return (isFileOpen); } //Gets input from user. Returns false and sets input to 0 if entry is not an int. bool getInt(int& innum) { bool valid = true; cin >> innum; if (!cin.good()) { cin.clear(); cin.ignore(numeric_limits::max(), '\n'); valid = false; innum = 0; } return valid; } //Find personnel infomation by first name and last name, or by phone number. Returns array location of match (-1 if no match) int findPerson(string dataArray[4][MV_3], int entries) { int menuVal = 0; string first, last; cout << "Chose search method: \n1)\tFirst name and last name\n2)\tPhone number\n3)\tCancel" << endl; while (!getInt(menuVal) || (menuVal > 3) || (menuVal < 1)) { cout << "Invalid input; enter again: "; } switch (menuVal) { case (1): cout << "Enter the first name (case sensitive): "; cin >> first; cout << "Enter the last name (case sensitive): "; cin >> last; for (int idx = 0; idx <= entries; idx++) { if (first == dataArray[0][idx]) { if (last == dataArray[1][idx]) { cout << "Match found at index " << idx << ":"; return (idx); } } } cout << "Person not found"; break; case (2): cout << "Enter the phone number in the format 012-345-6789: "; cin >> first; for (int idx = 0; idx <= entries; idx++) { if (first == dataArray[2][idx]) { cout << "Match found at index " << idx << ":"; return (idx); } } cout << "Person not found"; break; } return (-1); } //Displays information about selected person void displayEntry(string dataArray[4][MV_3], int entry) { cout << left; cout << setw(25) << dataArray[0][entry] << setw(25) << dataArray[1][entry] << setw(25) << dataArray[2][entry] << setw(25) << dataArray[3][entry]; }