0

I got these going which only sort the student's mark on an ascending order, but I can't sort the name and the ID of the students by their marks.

#include <iostream>
using namespace std;

int main()
{
    int total;
    cin >> total; // How much data you want to input

    string ID[100];
    string name[100];
    int grade[total];

    for (int i = 0; i < total; i++) // Inputting the data
    {
        cin >> ID[i]; // Student ID
        cin >> name[i]; // student name
        cin >> grade[i]; // student marks
    }

    for (int i = 0; i < total - 1; i++) {
        for (int j = i + 1; j < total; j++) {
            if (grade[j] < grade[i]) {
                int temp = grade[j];
                grade[j] = grade[i];
                grade[i] = temp;
            }
        }
    }

    for (int i = 0; i < total; i++) {
        cout << ID[i] << " " << name[i] << " " << grade[i] << endl;
    }
    return 0;
}
Marek R
  • 32,568
  • 6
  • 55
  • 140
Cactus
  • 3
  • 2
  • Swap name[i] and name[j] whenever you swap the grades. – L. Scott Johnson Oct 10 '22 at 13:08
  • 5
    `int nilai[total];` isn't valid C++. Are you using a compiler extension for variable length arrays? – Eljay Oct 10 '22 at 13:09
  • 1
    @Eljay: just rename the extension from .cpp to .c ;-) – Thomas Weller Oct 10 '22 at 13:10
  • @ThomasWeller `cin` and `cout` are not things that C defines – Caleth Oct 10 '22 at 13:11
  • Please provide a [mre]. Your code neither compiles as C nor as C++. – Thomas Weller Oct 10 '22 at 13:14
  • 2
    `int grade[total];` --> `std::vector grade(total);` – PaulMcKenzie Oct 10 '22 at 13:25
  • *How do I sort students ID, name, and marks of students* -- And if you had 4 or 5 other items associated with a student, you would quickly see how your code will be unmaintainable swapping all of those separate items. If you must have the student items as separate arrays, [See this answer](https://stackoverflow.com/questions/46382252/sort-array-by-first-item-in-subarray-c/46382976#46382976) -- the idea is to use an index array, and sort that based on the criteria and not all of those arrays. – PaulMcKenzie Oct 10 '22 at 13:35
  • The C++20 way: https://godbolt.org/z/sMEvzEh3d (as mentioned in answer your code is far from being even old c++). – Marek R Oct 10 '22 at 14:14

2 Answers2

4

IMHO your code is hardly C++ at all.

  • the only C++ things used are cout and cin
  • variable length array like int grade[total]; do not exist in C++, only in C.

If you had written a student class which combines ID, name and grade in a way that they can't be handled separately, you would always swap a complete student with its name and with its ID. You could then even use a C++ algorithm like std::sort.

Here's how that might look like. But wou could still write your own bubble sort algorithm.

#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
class Student
{
public:
    string ID{};
    string name{};
    int grade{};
};
int main() {

    int total;
    cin >> total; //How much data you want to input

    vector<Student> pupils(total);

    for (auto& student : pupils) //Inputting the data
    {
        cin >> student.ID; //Student ID
        cin >> student.name; //student name
        cin >> student.grade; //student marks
    }

    std::sort(pupils.begin(), pupils.end(),
        [](Student const& a, Student const& b) {return a.grade < b.grade; }
    );

    for (auto const& student : pupils)
    {
        cout << student.ID << " " << student.name << " " << student.grade << endl;
    }

    return 0;
}

Some remarks:

Thomas Weller
  • 55,411
  • 20
  • 125
  • 222
  • 2
    You are changing `pupils` whilst iterating over it. That wont end well. That may not even end at all. – Mike Vine Oct 10 '22 at 13:49
  • @MikeVine: sorry, push_back should be removed. It's a leftover from the previous version. Thanks for pointing it out. – Thomas Weller Oct 10 '22 at 13:50
  • I want to ask why the code I wrote works on devc++ but not on Microsoft Visual Studio? , I'm really new to programming and still have lots to learn. So right now I'm just learning the basics – Cactus Oct 10 '22 at 14:16
  • 1
    @Cactus: sorry, I don't know devc++. It looks rather old with support up to Windows XP. It uses GCC and maybe https://gcc.gnu.org/onlinedocs/gcc-3.4.6/gcc/Variable-Length.html#Variable-Length is activated – Thomas Weller Oct 10 '22 at 14:21
0

As mentioned by my comment, another alternative is to not sort the arrays themselves, but to sort an index array.

This allows you to keep the arrays separate, and without having to write n sets of "swap code" if you have n arrays to handle.

Below is mostly your code, but with what has been mentioned being applied:

#include <iostream>
#include <string>

int main() 
{
    int total;
    std::cin >> total; 
    std::string ID[100];
    std::string name[100];
    int grade[100];
    int index[100];

    for (int i = 0; i < total && i < 100; i++) //Inputting the data
    {
        std::cin >> ID[i]; //Student ID
        std::cin >> name[i]; //student name
        std::cin >> grade[i]; //student marks 
        index[i] = i;  // must be set up (0, 1, 2, 3, ..., total-1)
    } 

    for (int i = 0; i < total-1; i++) 
    {
        for (int j = i + 1; j < total; j++) 
        {
            // If necessary, swap index[i] and index[j] if the
            // grades at those locations are out of order
            if (grade[index[j]] < grade[index[i]]) 
            {
                int temp = index[j];
                index[j] = index[i];
                index[i] = temp;
            }
        }
    } 

    // Output the sorted data using the index array 
    for (int i = 0; i < total; i++) {
        std::cout << ID[index[i]] << " " << name[index[i]] << " " << grade[index[i]] << std::endl;
    }

    // For reference, output the final index array.
    std::cout << "\nIndex Array:\n";
    for (int i = 0; i < total; i++) {
        std::cout << index[i] << " ";
    }
}

Input:

4 
1 Joe 50
2 Jack 40
3 Mary 80
4 Sam 75

Output:

2 Jack 40
1 Joe 50
4 Sam 75
3 Mary 80

Index Array:
1 0 3 2 
PaulMcKenzie
  • 34,698
  • 4
  • 24
  • 45
  • I want to ask how does it know if it's taking the ID, name, and marks I inputted for the line ` std::cout << ID[index[i]] << " " << name[index[i]] << " " << grade[index[i]] << std::endl;` – Cactus Oct 10 '22 at 15:05
  • Not sure what you are asking. The arrays you inputted have not been swapped at all. It is the index array that has the "swap information". – PaulMcKenzie Oct 10 '22 at 15:07
  • And why do i need to put ` index[i] = i; ` – Cactus Oct 10 '22 at 15:10
  • See my edits. You need to set up the index array with the original index order. Follow the code, and you will see why the index array is initially set up this way. That's why it's called an "index array" -- it contains the indices of the swapped values. It originally starts out as `0,1,2,3,...,n-1`. After the swaps are done, it will contain those values, but swapped according to the criteria. – PaulMcKenzie Oct 10 '22 at 15:13