C++ Sort class array using qsort - c++

C++:
I'm trying to sort some students that are stored in a class by average media.
Only qsort, don't advice me of std::sort, thank you!
Qsort compare function:
int cmp(Student *a, Student *b) {
return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}
qsort call:
qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);
There's no compiler error, but it won't sort.
#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
using namespace std;
class Student {
private:
char name[20];
char surname[20];
int *marks;
int group;
float avg_mark;
public:
Student()
{
char na[20], sur[20];
int group;
cout << "\nEnter name: ";
cin >> na;
cout << "\nEnter surname: ";
cin >> sur;
cout << "\nEnter group: ";
cin >> group;
init(na, sur, group);
}
~Student()
{
cout << "\ndestructor";
delete []marks;
}
void init(char *n, char *p, int gr)
{
strcpy(name, n);
strcpy(surname, p);
group = gr;
marks = new int[6];
for (int i = 0; i < 6; i++)
{
cout << "\nEnter mark " << i + 1 << ": ";
cin >> *(marks + i);
}
avg_mark = media();
}
float media()
{
int s = 0;
for (int i = 0; i < 6; i++)
s += marks[i];
return ((float)s / 6);
}
void set_name(char *n)
{
strcpy(name, n);
}
char* get_name()
{
return name;
}
void set_surname(char *p)
{
strcpy(name, p);
}
char* get_surname()
{
return surname;
}
int get_group()
{
return group;
}
float get_media()
{
return avg_mark;
}
};
int cmp(Student *a, Student *b);
int comparator(void *a, void *b) {
return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}
void main(void)
{
int n;
cout << "\nEnter n: ";
cin >> n;
Student *tab = new Student[n];
for (int i = 0; i < n; i++)
cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl;
//qsort(&tab[0], (size_t)n, sizeof(tab), (int*)cmp);
cout << endl;
qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);
for (int i = 0; i < n; i++)
cout << i + 1 << ". " << tab[i].get_name() << " " << tab[i].get_surname() << " Group:" << tab[i].get_group() << " Average mark: " << tab[i].get_media() << endl;
cin.ignore();
cin.get();
}
int cmp(Student *a, Student *b) {
return (int)(((Student *)b)->get_media() - ((Student *)a)->get_media());
}

qsort(&tab, (size_t)n, sizeof(tab), (int(*)(const void*, const void*))cmp);
&tab is the address of the pointer tab. You want to pass the address of the first element of your array. That's &tab[0] or simply tab.
Also, you need to pass the size of a Student object, not the size of a pointer. So change sizeof(tab) to sizeof(Student) or sizeof(*tab). So the call should look like this:
qsort(tab, (size_t)n, sizeof(*tab), (int(*)(const void*, const void*))cmp);

Related

How do I convert from arrays to STL vectors?

In my class we recently got introduced to STL vectors. My professor has given us a program that uses arrays, and we are to convert it to use std::vectors instead. He would like us to use iterators, so we're not allowed to use square brackets, the push_back member function, or the at member function. Here's one of the for loops from the program I have to convert:
void readData(Highscore highScores[], int size)
{
for(int index = 0; index < size; index++)
{
cout << "Enter the name for score #" << (index + 1) << ": ";
cin.getline(highScores[index].name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << (index + 1) << ": ";
cin >> highScores[index].score;
cin.ignore();
}
cout << endl;
}
`
I'm just not quite understanding how to convert them. so far, I was kind of able to get this: for (vector <Highscore> :: iterator num = scores.begin(); num < scores.end(); num++)for the for loop. It doesn't quite make sense to me so I was hoping I can get some more tips or even more information on how to convert them. I don't want an answer, simply just a tip. Thank you! (if its of any help, this is the program I am having to convert and these are the four headers we have to use
void getVectorSize(int& size);
void readData(vector<Highscore>& scores);
void sortData(vector<Highscore>& scores);
vector<Highscore>::iterator findLocationOfLargest(
const vector<Highscore>::iterator startingLocation,
const vector<Highscore>::iterator endingLocation);
void displayData(const vector<Highscore>& scores);
above are the headers that have to be used (having to use these instead of the programs headers)
#include <iostream>
using namespace std;
const int MAX_NAME_SIZE = 24;
struct Highscore{
char name[MAX_NAME_SIZE];
int score;
};
void getArraySize(int& size);
void readData(Highscore highScores[], int size);
void sortData(Highscore highScores[], int size);
int findIndexOfLargest(const Highscore highScores[], int startingIndex, int size);
void displayData(const Highscore highScores[], int size);
int main()
{
Highscore* highScores;
int size;
getArraySize(size);
highScores = new Highscore[size];
readData(highScores, size);
sortData(highScores, size);
displayData(highScores, size);
delete [] highScores;
}
void getArraySize(int& size){
cout << "How many scores will you enter?: ";
cin >> size;
cin.ignore();
}
void readData(Highscore highScores[], int size)
{
for(int index = 0; index < size; index++)
{
cout << "Enter the name for score #" << (index + 1) << ": ";
cin.getline(highScores[index].name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << (index + 1) << ": ";
cin >> highScores[index].score;
cin.ignore();
}
cout << endl;
}
void sortData(Highscore highScores[], int numItems) {
for (int count = 0; count < numItems - 1; count++){
swap(highScores[findIndexOfLargest(highScores, count, numItems)],
highScores[count]);
}
}
int findIndexOfLargest(const Highscore highScores[], int startingIndex, int numItems){
int indexOfLargest = startingIndex;
for (int count = startingIndex + 1; count < numItems; count++){
if (highScores[count].score > highScores[indexOfLargest].score){
indexOfLargest = count;
}
}
return indexOfLargest;
}
void displayData(const Highscore highScores[], int size)
{
cout << "Top Scorers: " << endl;
for(int index = 0; index < size; index++)
{
cout << highScores[index].name << ": " << highScores[index].score << endl;
}
}
You maybe looking for one of two things.
If you want to add something to a vector, the function is push_back
vecScores.push_back(value) ; //in a for loop.
https://www.cplusplus.com/reference/vector/vector/push_back/
If you want to add something to a map, you could just use the form of
mapScore[index]=value ; // in a for loop.
https://www.cplusplus.com/reference/map/map/operator[]/
Probably your professor wants you to write something like this:
void readData(std::vector<Highscore>& highScores)
{
for (auto it = highScores.begin(); it != highScores.end(); ++it) {
cout << "Enter the name for score #" << std::distance(highScores.begin(), it) << ": ";
cin.getline(it->name, MAX_NAME_SIZE, '\n');
cout << "Enter the score for score #" << std::distance(highScores.begin(), it) << ": ";
cin >> it->score;
cin.ignore();
}
cout << endl;
}
where it is the iterator that's incremented via ++it from highScores.begin() to just before highScores.end(); then you access the members of the highScores's element "pointed by" it via it->member.
Here's a complete demo.
By the way, considering how much your professor likes void(some_type&) functions (and using namespace std;, if that was not your own idea), I would doubt you have much to learn from him. You better buy a good book.
I would do it like this, also get used to typing std::
Why is "using namespace std;" considered bad practice?
Also be careful with signed/unsigned, be precise about it.
If something can't have a negative value use unsigned types (or size_t)
#include <iostream>
#include <string>
#include <vector>
struct HighScore
{
std::string name;
unsigned int score;
};
// use size_t for sizes (value will always >0)
std::vector<HighScore> GetHighScores(size_t size)
{
std::vector<HighScore> highScores;
std::string points;
for (size_t index = 0; index < size; index++)
{
HighScore score;
std::cout << "Enter the name for score #" << (index + 1) << ": ";
std::cin >> score.name;
std::cout << "Enter the score for score #" << (index + 1) << ": ";
std::cin >> points;
// convert string to int
score.score = static_cast<unsigned int>(std::atoi(points.c_str()));
highScores.push_back(score);
}
std::cout << std::endl;
return highScores;
}
int main()
{
auto highScores = GetHighScores(3);
return 1;
}

Organizing names by last name with three of the same surnames (C++)?

I have an assignment to sort a list of names alphabetically by last name. However, there are three names with the same surname and I can't get the first names to alphabetize with the surnames. Have to code own bubble sort or other sorting algorithm. I chose bubblesort because it's one of the only ones we've learned so far. Any help is appreciated. Everything works except the correct assortment.
Here is my code:
// my name
// Program 6
// This program will show a list of names in a variety of orders.
#include <iostream>
#include <fstream>
#include <string>
using namespace std;
const int size = 25;
void showContacts_FNLN(string fnameArray[], string lnameArray[], int size);
void showContacts_LNFN(string lnameArray[], string fnameArray[], int size);
void reverseContacts_FNLN(string fnameArray[], string lnameArray[], int size);
void reverseContacts_LNFN(string fnameArray[], string lnameArray[], int size);
void searchLasname(string lnameArray[], string fnameArray[], int size);
void searchFirname(string fnameArray[], string lnameArray[], int size);
void bubbleSort(string lnameArray[], string fnameArray[], int size);
int main(int argc, const char * argv[])
{
int count = 0;
int ans;
ifstream nameData;
string lnameArray[size];
string fnameArray[size];
string lname, fname;
nameData.open("names.txt");
while(nameData >> fname >> lname)
{
fnameArray[count] = fname;
lnameArray[count] = lname;
count ++;
}
bubbleSort(lnameArray, fnameArray, size);
while(ans != 9)
{
cout << "What would you like to do?" << endl;
cout << "1) display contacts by first name and last name" << endl;
cout << "2) display contacts by last name and first name" << endl;
cout << "3) display contacts by first name and last name in reverse order" << endl;
cout << "4) display contacts by last name and first name in reverse order" << endl;
cout << "5) search for contact by last name" << endl;
cout << "6) search for contact by first name" << endl;
cout << "9) exit" << endl;
cout << "Enter: ";
cin >> ans;
cout << endl;
switch(ans)
{
case 1: showContacts_FNLN(fnameArray, lnameArray, size); // shows contacts in FN-LN order
break;
case 2: showContacts_LNFN(lnameArray, fnameArray, size); // LN-FN order
break;
case 3: reverseContacts_FNLN(fnameArray, lnameArray, size); // reversed FN-LN order
break;
case 4: reverseContacts_LNFN (fnameArray, lnameArray, size); // reversed LN-FN order
break;
case 5: searchLasname(lnameArray, fnameArray, size); // searches based on LN
break;
case 6: searchFirname(fnameArray, lnameArray, size); // searches based on FN
break;
case 9: cout << "Goodbye!" << endl;
break;
}
}
nameData.close();
return 0;
}
void showContacts_FNLN(string fnameArray[], string lnameArray[], int size)
{
for(int i=0; i<size; i++)
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
}
cout << endl;
}
void showContacts_LNFN(string lnameArray[], string fnameArray[], int size)
{
for(int i=0; i<size; i++)
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
}
cout << endl;
}
void reverseContacts_FNLN(string fnameArray[], string lnameArray[], int size)
{
for(int i=(size-1); i>=0; i--)
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
}
cout << endl;
}
void reverseContacts_LNFN(string fnameArray[], string lnameArray[], int size)
{
for(int i=(size-1); i>=0; i--)
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
}
cout << endl;
}
void searchLasname(string lnameArray[], string fnameArray[], int size)
{
int c = 0;
string slnam;
cout << "Enter a last name: ";
cin >> slnam;
for(int i=0; i<size; i++)
{
if(slnam==lnameArray[i])
{
cout << lnameArray[i] << ", " << fnameArray[i] << endl;
c++;
}
}
if (c == 0)
{
cout << "There is no match.";
cout << endl;
}
cout << endl;
}
void searchFirname(string fnameArray[], string lnameArray[], int size)
{
int c = 0;
string sfnam;
cout << "Enter a first name: ";
cin >> sfnam;
for(int i=0; i<size; i++)
{
if(sfnam==fnameArray[i])
{
cout << fnameArray[i] << " " << lnameArray[i] << endl;
c++;
}
}
if (c==0)
{
cout << "There is no match." << endl;
}
cout << endl;
}
void bubbleSort(string lnameArray[], string fnameArray[], int size)
{
string tmp, tmp2;
//int count=0;
for( int i = 1; i <= size - 1; i++ )
{
for( int j = 0; j < size - i; j++ )
{
//count++;
if( lnameArray[j] > lnameArray[j+1] )
{
tmp = lnameArray[j];
lnameArray[j] = lnameArray[j+1];
lnameArray[j+1] = tmp;
}
if(lnameArray[j] == lnameArray[j+1])
{
if(fnameArray[j] > fnameArray[j+1])
{
tmp = lnameArray[j];
lnameArray[j] = lnameArray[j+1];
lnameArray[j+1] = tmp;
tmp2 = fnameArray[j];
fnameArray[j] = fnameArray[j+1];
fnameArray[j+1] = tmp2;
}
}
}
}
//cout << "count = " << count << endl;
}
Here you go:
void bubbleSort(string lnameArray[], string fnameArray[], int size)
{
for( int i = 0; i < size - 1; i++ )
{
for( int j = 0; j < size - i - 1; j++ )
{
string name1 = lnameArray[j] + fnameArray[j];
string name2 = lnameArray[j + 1] + fnameArray[j + 1];
if(name1.compare(name2) > 0)
{
string tmp = lnameArray[j];
lnameArray[j] = lnameArray[j + 1];
lnameArray[j + 1] = tmp;
tmp = fnameArray[j];
fnameArray[j] = fnameArray[j + 1];
fnameArray[j + 1] = tmp;
}
}
}
}
Instead of having another 'if' for those that have similar last names, I combined the last name and the first name instead then used it for comparison.
I also noticed in your code in for( int j = 0; j < size - i; j++ ) that you forgot to add - 1 after size - i. Once j == size - i - 1 (assuming that i == 0 currently) then you use j + 1 to access an index, this will cause a segmentation fault since you're accessing an index beyond its range.
Your sort doesn't work because you change the position of the last names only (except for the case where two last names are equal.)
You should use a struct to store this information together in one array. Then you can simplify your code a lot:
struct Person {
Person() = default;
Person(string firstname, string lastname) : firstname(std::move(firstname)), lastname(std::move(lastname)) {}
string firstname;
string lastname;
};
void showContacts_FNLN(Person personArray[], int size) {
for (int i = 0; i < size; i++) {
cout << personArray[i].firstname << " " << personArray[i].lastname << endl;
}
cout << endl;
}
void bubbleSort(Person personArray[], int size) {
for (int i = 1; i <= size - 1; i++) {
// The condition must size - i - 1 because otherwise personArray[j+1] is faulty
for (int j = 0; j < size - i - 1; j++) {
if (personArray[j].lastname > personArray[j+1].lastname
|| (personArray[j].lastname == personArray[j+1].lastname &&
personArray[j].firstname > personArray[j+1].firstname)) {
auto tmp = std::move(personArray[j]);
personArray[j] = std::move(personArray[j+1]);
personArray[j+1] = std::move(tmp);
}
}
}
}
int main(int argc, const char * argv[]) {
int count = 0;
ifstream nameData;
Person personArray[size];
string lname, fname;
nameData.open("names.txt");
while(nameData >> fname >> lname) {
personArray[count] = Person(fname, lname);
count++;
}
nameData.close();
bubbleSort(personArray, size);
showContacts_FNLN(personArray, size);
return 0;
}
I removed some non-essential parts from this example to keep it very short but you should get the idea. (Note that my code makes use of C++11 move semantics, if this confuses you, just remove them.)
Some more suggestions:
Do not use using namespace std;. (The internet will tell you why.)
If you can, use std::array, which eliminates the need to always pass the size of the arrays and allows you to use a C++11 range for loop.

Can't store anything into my arrays

Having trouble storing strings into an array. I tried a multi-dimensional char array but it didn't work. I would ideally like a multi-dimensional string array but every time I try I get the error
cannot convert std::string (*)[100] {aka std::basic_string<char> (*)[100]} to std::string*
Don't even understand what that means. I tried printing the array in my function input_new_student which is where I store the string just to test it, and no luck. The same thing is happening to all my arrays. I've looked it up but I feel like im overlooking something very simple, please help.
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
void print_menu();
int get_selection();
std::string get_Name();
float get_GPA();
int get_Year();
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[]);
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[]);
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size);
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum);
using namespace std;
int main()
{
std::string student_names[100];
float student_GPA[100];
int student_start_year[100];
int ramapo_id[100];
int userChoice;
int index = 0;
int size = 0;
float sum = 0.0;
do
{
print_menu();
userChoice = get_selection();
if (userChoice == 1)
{
input_new_student(student_names, student_GPA, student_start_year, index, ramapo_id);
index++;
}
if (userChoice == 2)
{
print_all(student_names, student_GPA, student_start_year, index, size, ramapo_id);
}
if (userChoice == 3)
{
print_by_year(student_names, student_GPA, student_start_year, index, size);
}
if (userChoice == 4)
{
print_statistics(student_names, student_GPA, student_start_year, index, size, sum);
}
if (userChoice == 5)
{
return 0;
}
} while(userChoice > 0 && userChoice < 4);
return 0;
}
void print_menu()
{
cout << "Please pick from the following menu " << endl;
cout << "1. Add a new student " << endl;
cout << "2. Print all students " << endl;
cout << "3. Print students by year " << endl;
cout << "4. Print student statistics " << endl;
cout << "5. Quit" << endl;
}
int get_selection()
{
int userChoice;
cin >> userChoice;
while (userChoice > 4 || userChoice < 1)
{
cout << "Error: Invalid input, please try again: ";
cin >> userChoice;
}
return userChoice;
}
string get_Name()
{
std::string student_name;
cout << "Please enter the student's name: ";
cin >> student_name;
return student_name;
}
float get_GPA()
{
float student_GPA;
cout << "Please enter the GPA: ";
cin >> student_GPA;
return student_GPA;
}
int get_Year()
{
int student_year;
cout << "Please enter the start Year: ";
cin >> student_year;
return student_year;
}
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[])
{
//information generation
srand((unsigned)time(0));
int random_integer = rand();
ramapo_id[index] = random_integer;
//information acquisition
student_names[index] = get_Name();
student_GPA[index] = get_GPA();
student_start_year[index] = get_Year();
}
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[])
{
for (int i = 0; i < size; i++) {
cout << student_names[i] << " - " << ramapo_id[i] << endl;
}
}
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size)
{
int student_year_identifier;
cout << "Which year would you like to display?: ";
cin >> student_year_identifier;
for (int i = 0; i < size; i++)
{
if (student_year_identifier == student_start_year[i])
{
cout << "There were " << index << "students in that year" << endl;
}
else {
cout << "There were no students in that year" << endl;
}
}
}
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum)
{
cout << "Total: " << index << endl;
float avg = 0.0;
for (int i = 0; i < size; ++i)
{
sum += student_GPA[i];
}
avg = ((float)sum)/size;
cout << "GPA: " << avg << endl;
}
I recommend you have a container of structures rather than multiple containers:
struct Student_Info
{
std::string name;
double gpa;
unsigned int starting_year;
}
typedef std::vector<Student_Info> Student_Info_Container;
Student_Info_Container database;
// You could also have an array of student information:
static const size_t MAXIMUM_STUDENTS = 32U;
Student_Info_Container student_information[MAXIMUM_STUDENTS];
Placing the information into a structure support encapsulation and makes the program more efficient.
With parallel arrays, there is a possibility of synchronization issues. For example, the GPA for student 3 may be at index 4 of the array.
If you are restricted to arrays, you would only need to pass 2 parameters to your functions, the array and the capacity of the array.
There are few issues with your code, e.g.:
Your code is difficult to debug because you are using infinite while loops while taking input (e.g. in main and get_selection function).
How would you know if your code is working? At least, print something which indicates that your code is working, like cout << "Student added suuccessfully"; in input_new_student function.
I made these above mentioned changes and you can see that (at least) your code is working for option 1 at http://ideone.com/D5x8Eh
PS: I didn't get that compilation error, you should mention the compiler and flags you are using.
So as an update, the reason I wasn't able to print my array was begin I was not incrementing in my for loop. Thanks to #milesbudnek , #dreschjerm. I was able to see that my code was actually printing by adding the messages, this was prior to the suggestions, but thanks for the suggestion. Here is the code as it is now. Currently I just need to find a way to find values in the array (which I will search for) and create the multi-dimensional array for the strings.
#include <iostream>
#include <iomanip>
#include <string>
#include <cstdlib>
#include <ctime>
void print_menu();
int get_selection();
std::string get_Name();
float get_GPA();
int get_Year();
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[]);
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[]);
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size);
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum);
using namespace std;
int main()
{
std::string student_names[100];
float student_GPA[100];
int student_start_year[100];
int ramapo_id[100];
int userChoice;
int index = 0;
int size = 0;
float sum = 0.0;
//seed
srand((unsigned)time(0));
do
{
print_menu();
userChoice = get_selection();
if (userChoice == 1)
{
input_new_student(student_names, student_GPA, student_start_year, index, ramapo_id);
index++;
size++;
}
if (userChoice == 2)
{
print_all(student_names, student_GPA, student_start_year, index, size, ramapo_id);
}
if (userChoice == 3)
{
print_by_year(student_names, student_GPA, student_start_year, index, size);
}
if (userChoice == 4)
{
print_statistics(student_names, student_GPA, student_start_year, index, size, sum);
}
if (userChoice == 5)
{
return 0;
}
} while(userChoice > 0 && userChoice < 5);
return 0;
}
void print_menu()
{
cout << "Please pick from the following menu " << endl;
cout << "1. Add a new student " << endl;
cout << "2. Print all students " << endl;
cout << "3. Print students by year " << endl;
cout << "4. Print student statistics " << endl;
cout << "5. Quit" << endl;
}
int get_selection()
{
int userChoice;
cin >> userChoice;
while (userChoice > 5 || userChoice < 1)
{
cout << "Error: Invalid input, please try again: ";
cin >> userChoice;
}
return userChoice;
}
string get_Name()
{
std::string student_name;
cout << "Please enter the student's name: ";
cin >> student_name;
return student_name;
}
float get_GPA()
{
float student_GPA;
do {
cout << "Please enter the GPA: ";
cin >> student_GPA;
} while(!(student_GPA < 4.0 && student_GPA > 0.0));
return student_GPA;
}
int get_Year()
{
int student_year;
do {
cout << "Please enter the start Year: ";
cin >> student_year;
} while(!(student_year > 1972 && student_year < 2015));
return student_year;
}
void input_new_student(std::string student_names[], float student_GPA[], int student_start_year[], int index, int ramapo_id[])
{
//information generation
int random_integer = rand()%900000 + 100000;
ramapo_id[index] = random_integer;
//information acquisition
student_names[index] = get_Name();
student_GPA[index] = get_GPA();
student_start_year[index] = get_Year();
//Notification
cout << endl;
cout << "The student with R# " << random_integer << " was created." << endl;
cout << endl;
}
void print_all(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, int ramapo_id[])
{
cout << endl;
for (int i = 0; i < size; i++) {
cout << student_names[i] << " - " << ramapo_id[i] << endl;
}
cout << endl;
}
void print_by_year(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size)
{
int student_year_identifier;
//to trigger the response that there ARE students in that year
bool trigger;
int student_count = 0;
cout << "Which year would you like to display?: ";
cin >> student_year_identifier;
for (int i = 0; i < size; i++)
{
if (student_start_year[i] == student_year_identifier)
{
bool trigger = true;
student_count++;
}
}
if (trigger = true) {
cout << endl;
cout << "There are " << student_count << " student(s) in that year" << endl;
cout << endl;
}
else {
cout << endl;
cout << "There are no students in that year." << endl;
cout << endl;
}
}
void print_statistics(std::string student_names[], float student_GPA[], int student_start_year[], int index, int size, float sum)
{
//Print Total
cout << "Total: " << index << endl;
//Print GPA average
int smart_kids = 0;
float avg = 0.0;
for (int i = 0; i < size; ++i)
{
sum += student_GPA[i];
}
avg = ((float)sum)/size;
cout << "GPA: " << std::setprecision(3) << avg << endl;
//Print # of students above 2.0
for (int i = 0; i < size; i++)
{
if (student_GPA[i] > 2.0)
{
smart_kids++;
}
}
cout << "Above a 2.0: " << smart_kids << endl;
}

7.6 from C++ Primer

int main()
{
cout << "The maximum number of elements in an array is 100. " << endl;
const int MAX = 100;
double myarray[MAX];
int arraysize = Fill_Array(myarray, MAX);
Show_Array(myarray, arraysize);
Reverse_Array(myarray, arraysize);
Show_Array(myarray, arraysize);
Reverse_Positions(myarray, arraysize);
Show_Array(myarray, arraysize);
return 0;
}
int Fill_Array(double ar[], int size)
{
int i = 0;
cout << "\nEnter a double value (Enter q to quit): ";
while (cin >> ar[i] && i < size)
{
i++;
cout << "Enter next value: ";
}
return i;
}
void Show_Array(const double ar[], int size)
{
cout << "\nHere is your array: " << endl << endl;
for (int i = 0; i < size; ++i)
cout <<"\#"<<i+1<<" is "<<ar[i] << endl;
}
void Reverse_Array(double ar[], int size)
{
cout << "Now we reverse the whole array: " << endl;
for (int i = 0; i != size / 2; ++i)
{
double temp;
temp = ar[i];
ar[i] = ar[size - 1 - i];
ar[size - 1 - i] = temp;
}
}
void Reverse_Positions(double ar[], int size)
{
cout << "Enter two positions: " << endl;
int a, b;
if (cin >> a >> b)
{
double temp = ar[b - 1];
ar[b - 1] = ar[a - 1];
ar[a - 1] = temp;
}
}
Something wrong with reverse_position function: It only shows "Enter two positions" and then the function terminates. There is no chance for me to enter the integers a and b. I doubt there is something wrong with the input queue, but I am not sure.

How to sort a class array

I am trying to sort a class array that has 5 values inside of it. 3 strings and 2 ints. I would like to sort the array from highest to lowest on the int values but can't figure out how to do so. My though process is to send the array into the class and then pull out the correct int value and sort for each array location without changing the other values of that location.
How can I pull out these values so that I can sort them accordingly? If I could then I would know how to finish my code.
If there is an easier way to do this then I am open to any suggestions.
In the code below I have a template of what I would do if I could pull that number out:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class Thing
{
public:
Thing();
void setvariables(string s, string g, string a, int y, int l);
void get();
void print();
void sort_time(Thing data[], int datasize);
private:
string name;
string genre;
string artist;
int year;
int length;
};
Thing::Thing()
{
name = "";
genre = "";
artist = "";
year = 13;
length = 15;
}
void Thing::setvariables(string n, string g, string a, int y, int l)
{
name = n;
genre = g;
artist = a;
year = y;
length = l;
}
/* void Thing::sort_time(Thing data[], int datasize)
{
int lar_pos, pos, lar_val;
for (int index = 0; index < datasize; index++)
{
lar_pos = index;
lar_val = data[index].get();
for (pos = index; pos < datasize; pos++)
{
if (data[pos] > data[lar_pos])
{
lar_pos = pos;
lar_val = data[lar_pos];
}
}
data[lar_pos] = data[index];
data[index] = lar_val;
}
}
void Thing::get()
{
l = length;
}
*/
void Thing ::print()
{
cout << setw(25) << name << setw(10) << genre << setw(5) << year
<< setw(30) << artist << setw(5) << length << endl;
}
int main()
{
// Create array of things
int size = 9;
Thing array[9];
// Initialize array of things
for (int i = 0; i<size; i++)
{
string name, genre, artist, junk;
int year, length;
getline(cin, name);
getline(cin, genre);
getline(cin, artist);
cin >> year;
cin >> length;
array[i].setvariables(name, genre, artist, year, length);
cin.ignore(256, '\n');
}
// Print array of things
cout << setw(25) << "TITLE" << setw(10) << "GENRE" << setw(5) << "YEAR"
<< setw(30) << "ARTIST" << setw(5) << "TIME" << endl;
cout << setw(25) << "=====" << setw(10) << "=====" << setw(5) << "===="
<< setw(30) << "======" << setw(5) << "====" << endl;
for (int i = 0; i<size; i++)
array[i].print();
return 0;
}
Use std::sort with a custom comparator or define operator< for your type.
Example:
#include <algorithm>
class Thing
{
// ...
};
class ThingComparator
{
bool operator()(const Thing& a, const Thing& b)
{
// Define your logic here and return true if a is considered lesser than b.
}
};
int main()
{
const int size = 9; // Make it constant!!
Thing array[size];
// Fill the array ...
// Then sort it
std::sort(array, array + size, ThingComparator());
}