// Name: msglm // Date: Oct 3rd, 2022 // Program Name: Midterm // Description: Read in a file, sanitize said file of html tags, output the contents in a format sorted that the user chooses. //90% of this is self-plagiarism, or as I like to call it, recycled //and think, some people get really angry about reuse! //I never understood that mentality, it's just absurd to me: //just never transfer your copyrights and also put your code //under a free software license and this won't be a problem. #include #include #include #include #include #include using namespace std; //Structures // Use a struct to: // Create an array or vector variable to store a person’s favorite movie // Create an array or vector variable to store when the year that movie was released // Create an array or vector variable to store the box office gross (total amount of money) it made // struct Person { vector favMov; vector yearReleased; vector gross; }; struct Movie { string favMov; string yearReleased; string gross; }; //initalizes the file //with the amount of times I used this function, I have to wonder //why I don't end up making my own standard library //or code processorsor to catconate some standard stuff void initalize(string location, ifstream & fileVar) { fileVar.open(location); if (!fileVar) { cout << "ERROR! " << location << " failed to open!"; exit(1); } } //borrowed code from another assignment // //it's great that I made this not have any side effects //I can just slap this down anywhere I please string sanitize(string userInput) { bool insideATag = false; bool metTheTagTerminator = false; int beginBracketPos; int endBracketPos; int tagLength; for (int charPos=0; charPos<=userInput.length();charPos++) { if (insideATag && metTheTagTerminator) { //Tag length only exists because std::String.erase() doesn't accept //a range, but rather a start and the chars to go. it's accursed. tagLength = (endBracketPos-beginBracketPos)+1; userInput.erase(beginBracketPos, tagLength); charPos = 0; insideATag = false; metTheTagTerminator = false; } if (userInput[charPos] == '<') { insideATag = true; beginBracketPos = charPos; } if (userInput[charPos] == '>' && insideATag) { metTheTagTerminator = true; endBracketPos = charPos; } } return userInput; } //takes a file as input and, for every 3 lines, puts it into the movieDataContainer's vectors //Will only run if the next line after a set of 3 is not EOF //there is no error checking Person orderAndAssociateIntoStruct(ifstream & fileVar) { Person movieDataContainer; string temp; int oscillate = 0; int epoch = 0; while(getline(fileVar, temp)) { switch (oscillate) { case 0: movieDataContainer.favMov.push_back(sanitize(temp)); oscillate++; break; case 1: movieDataContainer.yearReleased.push_back(sanitize(temp)); oscillate++; break; case 2: movieDataContainer.gross.push_back(sanitize(temp)); epoch++; oscillate = 0; break; if (fileVar.peek() != EOF) { break; } } } return movieDataContainer; } //Prints out all the data in a tabular format void output(vector movieDataContainer) { cout << left << setw(16) << "Movie Name" << " "; cout << left << setw(16) << "Year Published" << " "; cout << left << setw(16) << "Gross Box Office" << " "; for (Movie movie : movieDataContainer) { cout << endl; cout << left << setw(16) << movie.favMov; cout << left << setw(16) << movie.yearReleased; cout << left << setw(16) << movie.gross; } cout << endl; } //Bubble sort implementations // //depending on the menu option selected, this will sort by different values //The movieList is read for all the movie structs in it, those struct's values //are what are read when sorting happens. Depending on if the sorting deemes the values //greater or lesser, the swapping of the movie struct itself will happen // //It took many hours in gdb to discover that this function had a bug due to //movieList.size() returning 5 instead of 4 if 4 movie structs are in movieList // //The experience of debugging C++ seg faults is only comparable to one thing: passing a kidney stone; //It takes 3 hours of your life away, it's painful, and by the end of it, you'll be bleeding out of places //you never thought you could bleed out of. // //The only upside to debugging C++ code is that it doesn't bill your insurance... //well, it does end up billing it later on when the blood pressure problems start setting in, but right now that's not my problem. vector sort(vector movieList, int menuOption) { Movie temp; switch(menuOption) { case 1: for (int pos = 0; pos < movieList.size() - 1; pos++) { for (int comparePos = 0; comparePos < ((movieList.size() - 1) - pos); comparePos++) { if(movieList[comparePos].favMov > movieList[comparePos + 1].favMov) { temp = movieList[comparePos]; movieList[comparePos] = movieList[comparePos + 1]; movieList[comparePos + 1] = temp; } } } break; case 2: for (int pos = 0; pos < movieList.size() - 1; pos++) { for (int comparePos = 0; comparePos < ((movieList.size() - 1) - pos); comparePos++) { if(stof(movieList[comparePos].yearReleased) > stof(movieList[comparePos + 1].yearReleased)) { temp = movieList[comparePos]; movieList[comparePos] = movieList[comparePos + 1]; movieList[comparePos + 1] = temp; } } } break; case 3: for (int pos = 0; pos < movieList.size() - 1; pos++) { for (int comparePos = 0; comparePos < ((movieList.size() - 1) - pos); comparePos++) { if(stof(movieList[comparePos].gross) > stof(movieList[comparePos + 1].gross)) { temp = movieList[comparePos]; movieList[comparePos] = movieList[comparePos + 1]; movieList[comparePos + 1] = temp; } } } break; } return movieList; } //just a simple menu. returns a number because I don't feel like dealing with flags int menuOption() { int choice; //No input validation here since the rubric doesn't call for it. cout << "1. Sort by Movie Name\n"; cout << "2. Sort by Year Released\n"; cout << "3. Sort by Box office gross\n"; cout << "Enter Selection: "; cin >> choice; return choice; } //effectively inverts the person struct //instead of being a struct with vectors in it, it's a vector with structs in it //and those structs hold data about an individual movie // //This is achieved using a similar algorithm to reading in the file vector person2MovieList(Person person) { vector personsMovieList; int oscillate = 0; string tempfavMov; string tempyearReleased; string tempGross; int moviePos = 0; //Since gross and year release are associated with movie, we can assume //that for every movie, there should be a gross and year release. // //If this was in production, some type of check would be ran to ensure this while(moviePos < person.favMov.size()) { switch (oscillate){ case 0: tempfavMov = person.favMov[moviePos]; oscillate++; break; case 1: tempyearReleased = person.yearReleased[moviePos]; oscillate++; break; case 2: tempGross = person.gross[moviePos]; oscillate = 0; personsMovieList.push_back( Movie() ); personsMovieList[moviePos].favMov = tempfavMov; personsMovieList[moviePos].yearReleased = tempyearReleased; personsMovieList[moviePos].gross = tempGross; moviePos++; break; } } return personsMovieList; } int main() { //Variable declaration ifstream data; initalize("input.txt", data); Person organizedMovieData = orderAndAssociateIntoStruct(data); //This current data structure makes the sorting section a nightmare. //this is due to the lack of a hard associations between the movie's name, year of release, and gross profit // //I somehow must associate those three variables despite them being in an array //Instead of using an accursed flag system to accomplish this, I will instead opt to //just convert the data in the Person struct into a vector of Movie Structs //this way, the order of the struct may be managed much more simply vector personsMovieList = person2MovieList(organizedMovieData); output(sort(personsMovieList, menuOption())); data.close(); } /* This program is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License Version 3 ONLY as published by the Free Software Foundation. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details. You should have received a copy of the GNU Affero General Public License along with this program. If not, see . */