mpak
mpak

Reputation: 2518

Sorting struct-members by a specific value

I've had this problem for a while now so I thought it would be better to ask for direction. Tried search with no help and been struggling with this pretty long now so here we go.

I'm learning C++ and got hard time on this exercise: I have to save details of 3 students using struct and then print them in ascending order by their distance from school. First student's details are asked by user input and others are initialized by variables. Everything goes fine untill I have to sort them out.

At the moment I'm trying to pass an array to a sorting function, containing each students details which I entered manually to that array for testing purposes. I had some serious problems when I tried to initialize array directly from struct member values and then passing that array to sorting func. Also, in this exercise I must use C-arrays.

Perpaps someone can show me proper way of doing this? Maybe there is even easier way to do this? Thanks in advance! Here is my code:

EDIT: Platform: Windows 7, IDE: Visual Studio 2013

#include <iostream>
#include <algorithm>
#include <functional>

using namespace std;

struct personaldata {
    char firstname[50], lastname[50], address[50], postal[50];
    double distschool;
    int shoesize;
};

struct SortRecordsAscending
{
    bool operator()(const personaldata& lhs, const personaldata& rhs)
    {
        return (lhs.distschool < rhs.distschool);
    }
};

void SortingObjectsExample(personaldata *details, int SIZE)
{
    sort(details, details + SIZE, SortRecordsAscending());
    for (int i = 0; i < SIZE; ++i)
    {
        cout << details[i].firstname << " " << details[i].lastname << endl;
        cout << details[i].address << " " << details[i].postal << endl;
        cout << "Distance from school: " << details[i].distschool << endl;
        cout << "Shoe size: " << details[i].shoesize << endl;
        cout << endl;
    }
}

int main() {

    personaldata student1, student2, student3;
    const int SIZE(3); // Amount of students


    //Student 1
    cout << "Enter first name: ";
    cin.getline(student1.firstname, 50);

    cout << "Enter last name: ";
    cin.getline(student1.lastname, 50);

    cout << "Enter distance from school: ";
    cin >> student1.distschool;
    cin.ignore();

    cout << "Enter address: ";
    cin.getline(student1.address, 50);

    cout << "Enter postal: ";
    cin >> student1.postal;

    cout << "Enter shoe size: ";
    cin >> student1.shoesize;

    //Student 2
    strcpy_s(student2.firstname, 50, "Olli");
    strcpy_s(student2.lastname, 50, "Oppilas");
    student2.distschool = 9.4;
    strcpy_s(student2.address, 50, "Opiskelijakatu 5a 14");
    strcpy_s(student2.postal, 50, "40200");
    student2.shoesize = 39;

    //Student 3
    strcpy_s(student3.firstname, 50, "Ossi");
    strcpy_s(student3.lastname, 50, "Oppilas");
    student3.distschool = 8.4;
    strcpy_s(student3.address, 50, "Koululaiskatu 18b 2");
    strcpy_s(student3.postal, 50, "40100");
    student3.shoesize = 41;

    personaldata details[3] = {
            { "Oiva", "Oppilas", "Koivukatu 8B 16", "40100", 9.7, 43 },
            { "Ossi", "Oppilas", "Koululaiskatu 18b 2", "40100", 8.4, 41 },
            { "Olli", "Oppilas", "Lehtitie 3B 15", "401200", 8.7, 38 }
    };

    SortingObjectsExample(details, SIZE);

}

Code above works the way I want it to. However if I do like this:

personaldata details[3] = {
        { student1.firstname, "Oppilas", "Koivukatu 8B 16", "40100", 9.7, 43 },
        { student2.firstname, "Oppilas", "Koululaiskatu 18b 2", "40100", 8.4, 41 },
        { student3.firstname, "Oppilas", "Lehtitie 3B 15", "401200", 8.7, 38 }
};

SortingObjectsExample(details, SIZE);

I get from compiler

1>------ Build started: Project: Harj17, Configuration: Debug Win32 ------
1>  harj17.cpp
1>harj17.cpp(80): error C2440: 'initializing' : cannot convert from 'char (*)[50]' to 'char'
1>There is no context in which this conversion is possible
1>harj17.cpp(80): warning C4244: 'initializing' : conversion from 'double' to 'char', possible loss of data
1>harj17.cpp(80): error C2440: 'initializing' : cannot convert from 'char [50]' to 'char'
1>          There is no context in which this conversion is possible
========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

And if use pointer like this:

    personaldata details[3] = {
        { *student1.firstname, "Oppilas", "Koivukatu 8B 16", "40100", 9.7, 43 },
        { *student2.firstname, "Oppilas", "Koululaiskatu 18b 2", "40100", 8.4, 41 },
        { *student3.firstname, "Oppilas", "Lehtitie 3B 15", "401200", 8.7, 38 }
};

It will compile the program but with warning message and it doesn't work properly, it only prints first letter of person's first name.

    1>------ Build started: Project: Harj17, Configuration: Debug Win32 ------
1>  harj17.cpp
1>harj17.cpp(80): warning C4244: 'initializing' : conversion from 'double' to 'char', possible loss of data
1>  Harj17.vcxproj -> Harj17.exe
========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========

Here is the output when running the program. You can see problem with the names and other info gets screwed up too.

Enter first name: Example
Enter last name: Student
Enter distance from school: 13.37
Enter address: Example Address 6B 16
Enter postal: 1337
Enter shoe size: 43
EOppilas Koivukatu 8B 16
40100   +
Distance from school: 0
Shoe size: 0

OOppilas Koululaiskatu 18b 2
40100)
Distance from school: 0
Shoe size: 0

OOppilas Lehtitie 3B 15
401200&
Distance from school: 0
Shoe size: 0

Upvotes: 2

Views: 2011

Answers (1)

Neil Kirk
Neil Kirk

Reputation: 21763

It's strange you are allowed to use STL algorithms but not data structures. I'm not clear from your question what you are having difficulty with. Sorting the structs or constructing them? In any case here is a simple way to create and sort the structs. As your sort function doesn't require any state, it doesn't need to be a functor. It can just be a normal function.

To improve this further I would use a vector, add stream operators to the struct and use a constructor.

#include <algorithm>
using namespace std;

struct henkilotiedot { // Person first name, last name, address and postal
    string etunimi, sukunimi, osoite, postinumero;
    double koulumatka; // Distance from school
    int kengannumero; // Shoe size
};

bool SortByDistance(const henkilotiedot& lhs, const henkilotiedot& rhs)
{
    return lhs.koulumatka < rhs.koulumatka;
}

int main()
{
    const int SIZE = 3;
    henkilotiedot data[] = { { "blah", "blah", "blah", "blah", 5.0, 10 }, { "blah", "blah", "blah", "blah", 1.0, 10 }, { "blah", "blah", "blah", "blah", 15.0, 10 } };
    sort(data, data + SIZE, SortByDistance);
}

Upvotes: 1

Related Questions