1

I've tried nearly everything. Just looking for some tips.

The project is to read data from a file ["racers2011.txt"] into a struct and sort the race times for the males and sort the racetimes for the females. Group the males and the females serperately and output the with their rank and racetime, being their best blue race and their best red race combined. I have read the file in and output it to the new file, but cannot figure out how to sort the file.

If someone could help me out in the slightest it would be greatly appreciated.

Here is the code I have so far (some of the code I have does not compile so I have commented it out):

#include <iostream>
#include <cstring>
#include <fstream>

using namespace std;

struct Racer_struct
{
    int bib;
    char sex;
    char fname[30];
    char lname[30];
    double b1, b2, r1, r2;
};

bool connectInFile(ifstream& fin, char infilename[]);

bool connectOutFile(ofstream& fout, char outfilename[]);

void readData(ifstream& fin, Racer_struct racers[], const int& MAX);

//void racerGender(ostream& fout, Racer_struct racers[], const int& MAX);

//double calcTotalTime(Racer_struct racers[], double total[], const int& MAX);

void writeData(ostream& fout, Racer_struct racers[], const int& MAX);

int main()
{
    const int MAX = 38;
    Racer_struct racers[MAX];
//    double total[MAX];

    ifstream fin;
    ofstream fout;
    char in_file[30], out_file[30];
    bool opened;
    char title[79];

    opened = connectInFile(fin, in_file);
    cout << opened << endl;
    opened = connectOutFile(fout, out_file);
    cout << opened << endl;

    if(opened)
    {
        cout << "CONNECTED to: " << in_file << endl;
        cout << "WRITING to: " << out_file << endl;

        for(int i=0; i<=3; i++)
        {
            fin.getline(title, 80);
            fout << title << "\n";
        }
    }
    readData(fin, racers, MAX);
    writeData(fout, racers, MAX);

    fin.close();
    fout.close();
    cout << endl;
    return 0;
}

bool connectInFile(ifstream& fin, char infilename[])
{
    bool success = true;
    cout << "Enter input filename: ";
    cin >> infilename;
    fin.open(infilename);
    if(fin.fail())
        success = false;
    return success;
}

bool connectOutFile(ofstream& fout, char outfilename[])
{
    bool opened = true;
    cout << "Enter the filename you wish to write to: ";
    cin >> outfilename;
    fout.open(outfilename);
    if(fout.fail())
        opened = false;
    return opened;
}

void readData(ifstream& fin, Racer_struct racers[], const int& MAX)
{
    char ws;

    for(int i=0; i<MAX && fin.peek()!= EOF; i++)
    {
        fin >> racers[i].bib >> racers[i].sex >> racers[i].fname >> racers[i].lname
            >> racers[i].b1 >> racers[i].b2 >> racers[i].r1 >> racers[i].r2;
        fin.get(ws);
    }
}

/*
void racerGender(ostream& fout, Racer_struct racers[], const int& MAX)
{

    for(int i=0; i<MAX; i++)
        if(racers[i].sex == 'M')
        {
            calcTotalTime(racers, total, MAX);
            writeData(fout, racers, MAX);
        }
        else
        {
            calcTotalTime(racers, total, MAX);
            writeData(fout, racers, MAX);
        }
}

double calcTotalTime(Racer_struct racers[], double total[], const int& MAX)
{
    double total[MAX];

    for(int i=0; i<MAX; i++)
        if(racers[i].r1 > racers[i].r2 && racers[i].b1 > racers[i].b2)
            total[i] = racers[i].r2 + racers[i].b2;
        else if(racers[i].r2 > racers[i].r1 && racers[i].b2 > racers[i].b1)
            total[i] = racers[i].r1 + racers[i].b1;
        else if(racers[i].r1 > racers[i].r2 && racers[i].b2 > racers[i].b1)
            total[i] = racers[i].r2 + racers[i].b1;
        else
            total[i] = racers[i].b2 + racers[i].r1;
    return total[i];
}
*/

void writeData(ostream& fout, Racer_struct racers[], const int& MAX)
{
    for(int i=0; i<MAX; i++)
    {

        fout << racers[i].bib << "\t" << racers[i].sex << "\t" << racers[i].fname
             << "\t" << racers[i].lname << "\t" << racers[i].b1 << "\t" << racers[i].b2
             << "\t" << racers[i].r1 << "\t" << racers[i].r2 /*<< "\t" << total[i]*/ << endl;

/*      if((i+1)%5)
            fout << "\t";
        else
            fout << endl;
*/
    }
}
0

3 Answers 3

1

Use std::sort. Saying much more would give it away, and I imagine this is homework.

Sign up to request clarification or add additional context in comments.

7 Comments

this was homework, the semester is over I need this to study for my finals. "use std::sort" is not really much help to be honest. Could you elaborate maybe a bit more. If you could maybe look at my code and tell me where im going wrong with some of the stuff I have. That would be awesome. But any help is better than no help, so Thank you.
Try using std::sort in your code. It should be pretty straightforward, you just pass it some arguments to show it where your container is and give it a function to do the comparison. If you use a good compiler like clang (not g++), you should be able to sort it out fairly well with just the documentation and the compiler's diagnostics.
wouldnt it be easier in my case to use a swap function? calculate the total race times and swap them until the are ranked properly, for males and females and then fout them into the file that way.
As Clippy would say: it looks like you are thinking to implement bubble sort--do you need help with that?
a bubble sort, I will try that and see how that works out. Thanks gentlemen. Ill get back to you.
|
0

std::sort is a very efficient sorting function that is part of the C++ standard, in the header algorithm.

std::sort uses the concept of "iterators". It's a relatively tough subject, so I'm going to summarize it roughly here. Any sequence, in C++, can be represented as a pair of iterators: one points to the first element, and the second points to one spot after the last one (so, [begin, end[). This can easily be seen in arrays: for an array a with size N, a[N] is not part of the array. The iterator type for an array is a pointer.

So, let's look at how we can use std::sort in your case:

std::sort(racers, racers + MAX);

The above line can be read as "sort the elements in the sequence delimited by racers and racers + MAX". For an array, the name of the array points to the first element, and adding the size to that address gives the "end" iterator (like explained above). If you used a standard container, like std::vector, you would use the vector's begin() and end() methods to get the appropriate iterators.

Now, std::sort compares each element two-by-two using a comparing function. By default, that is the < operator (so elements are sorted in ascending order). An overload allows you to provide your own function when needed. In our case, overloading < for Racer_struct would be enough:

// This should be defined after Racer_struct and before the first call to std::sort
bool operator<(const Racer_struct &left, const Racer_struct &right)
{
    // return true if left should get before right
}

5 Comments

wouldnt it be easier in my case to use a swap function? calculate the total race times and swap them until the are ranked properly, for males and females and then fout them into the file that way.
You could always write your sort algorithm. What you're describing sounds like bubble sort, an awfully inefficient (but simple) algorithm. std::sort is very fast, and at least that way you don't have to reinvent the wheel.
im trying to use std::sort, just can't figure it out. How do I call it and what is it sorting and how does it know what its sorting.
I think I might need help figuring out how to calculate the total race times, then I could go through and sort the racers with that sort function using just the racetimes. Can you point me in the right direction for calculating the total race times. Ive got some code for it, but it is not working properly, so obviously im doing something wrong. maybe its in my parameter list?
std::sort makes use of a concept called "templates". If you sort an array of T, then std::sort will use an operator < that compares two T. Such an operator is defined by default for basic types, like int or float, as well as some classes (std::string for instance). When you want to sort something else, you'll have to define your own operator. That's what I'm doing above. Now, the fields of your struct aren't well named, so it's hard to know what to compare in order to sort them...
0

As John Zwinck said, you probably want to use std::sort to do the sorting. Personally, I'd overload operator>> and operator<< to the reading and writing. I'd also overload operator< to do the comparison.

With those in place, your top level code could look something like this:

typedef std::istream_iterator<Racer_struct> reader;

std::vector<Racer_struct> racers((reader(fin)), reader());

std::sort(racers.begin(), racers.end());

std::copy(racers.begin(), racers.end(), 
          std::ostream_iterator<Racer_struct>(std::cout, "\n"));

Given your criteria (keeping males separate from females) you probably want to treat sex as the primary field, then the times. This will group all the males together and all the females together (in an order of your choosing).

3 Comments

sorry jerry. thats a little above my head. Is there a simpler more basic way to do this?
A simpler way would be to use another programming language, like Python or bash.
you are able to sort structs without using dynamic arrays or even std::sort. Which would be simpler for me considering I haven't learned these methods yet, and that they will not be on my final exam. If you looked at my code you would see that I have the main components of the sorting in the, just having trouble implementing them. Like my racerGender() function, is it right, or my calcTotalTime() function, should that work?? Thanks john.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.