Считывание данных из файла в структуру, сортировка данных и запись в файл

#c

#c

Вопрос:

Я перепробовал почти все. Просто ищу несколько советов.

Проект заключается в считывании данных из файла [«racers2011.txt «] в структуру и отсортируйте время забега для мужчин и время забега для женщин. Последовательно сгруппируйте мужчин и женщин и выведите их с указанием их ранга и времени гонки, что является их лучшей синей расой и их лучшей красной расой вместе взятых. Я прочитал файл и вывел его в новый файл, но не могу понять, как отсортировать файл.

Если бы кто-нибудь мог мне хоть немного помочь, я был бы очень признателен.

Вот код, который у меня есть на данный момент (часть имеющегося у меня кода не компилируется, поэтому я его закомментировал):

 #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(ifstreamamp; fin, char infilename[]);

bool connectOutFile(ofstreamamp; fout, char outfilename[]);

void readData(ifstreamamp; fin, Racer_struct racers[], const intamp; MAX);

//void racerGender(ostreamamp; fout, Racer_struct racers[], const intamp; MAX);

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

void writeData(ostreamamp; fout, Racer_struct racers[], const intamp; 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(ifstreamamp; fin, char infilename[])
{
    bool success = true;
    cout << "Enter input filename: ";
    cin >> infilename;
    fin.open(infilename);
    if(fin.fail())
        success = false;
    return success;
}

bool connectOutFile(ofstreamamp; 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(ifstreamamp; fin, Racer_struct racers[], const intamp; MAX)
{
    char ws;

    for(int i=0; i<MAX amp;amp; 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(ostreamamp; fout, Racer_struct racers[], const intamp; 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 intamp; MAX)
{
    double total[MAX];

    for(int i=0; i<MAX; i  )
        if(racers[i].r1 > racers[i].r2 amp;amp; racers[i].b1 > racers[i].b2)
            total[i] = racers[i].r2   racers[i].b2;
        else if(racers[i].r2 > racers[i].r1 amp;amp; racers[i].b2 > racers[i].b1)
            total[i] = racers[i].r1   racers[i].b1;
        else if(racers[i].r1 > racers[i].r2 amp;amp; 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(ostreamamp; fout, Racer_struct racers[], const intamp; 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;
*/
    }
}
  

Ответ №1:

Используйте std::sort. Если сказать гораздо больше, это выдаст все, и я полагаю, что это домашнее задание.

Комментарии:

1. это было домашнее задание, семестр окончен, мне это нужно для подготовки к выпускным экзаменам. честно говоря, «use std::sort» не очень помогает. Не могли бы вы уточнить, возможно, немного больше. Если бы вы могли, возможно, взглянуть на мой код и сказать мне, где я ошибаюсь с некоторыми материалами, которые у меня есть. Это было бы потрясающе. Но любая помощь лучше, чем никакой, так что спасибо.

2. Попробуйте использовать std::sort в своем коде. Это должно быть довольно просто, вы просто передаете ему некоторые аргументы, чтобы показать, где находится ваш контейнер, и даете ему функцию для выполнения сравнения. Если вы используете хороший компилятор, такой как clang (не g ), вы должны быть в состоянии разобраться с этим достаточно хорошо, используя только документацию и диагностику компилятора.

3. не было бы проще в моем случае использовать функцию подкачки? вычислите общее время гонки и меняйте их местами, пока не будут правильно ранжированы мужчины и женщины, а затем перенесите их в файл таким образом.

4. Как сказал бы Клиппи: похоже, вы собираетесь реализовать пузырьковую сортировку — вам нужна помощь с этим?

5. пузырьковая сортировка, я попробую это и посмотрю, как это работает. Спасибо, господа. Я перезвоню вам.

Ответ №2:

std::sort это очень эффективная функция сортировки, которая является частью стандарта C , в заголовке algorithm .

std::sort использует концепцию «итераторов». Это относительно сложная тема, поэтому я собираюсь здесь ее в общих чертах обобщить. Любая последовательность в C может быть представлена в виде пары итераторов: один указывает на первый элемент, а второй указывает на одно место после последнего (так, [begin, end[ ). Это легко можно увидеть в массивах: для массива, a имеющего размер N , a[N] не является частью массива. Типом итератора для массива является указатель.

Итак, давайте посмотрим, как мы можем использовать std::sort в вашем случае:

 std::sort(racers, racers   MAX);
  

Приведенную выше строку можно прочитать как «отсортируйте элементы в последовательности, разделенной racers и racers MAX «. Для массива имя массива указывает на первый элемент, а добавление размера к этому адресу дает итератор «end» (как описано выше). Если бы вы использовали стандартный контейнер, например, std::vector , вы бы использовали методы вектора begin() и end() для получения соответствующих итераторов.

Теперь std::sort сравнивает каждый элемент два на два, используя функцию сравнения. По умолчанию это < оператор (поэтому элементы сортируются в порядке возрастания). Перегрузка позволяет вам предоставлять свою собственную функцию, когда это необходимо. В нашем случае было бы достаточно перегрузки < для Racer_struct :

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

Комментарии:

1. не было бы проще в моем случае использовать функцию подкачки? вычислите общее время гонки и меняйте их местами, пока не будут правильно ранжированы мужчины и женщины, а затем перенесите их в файл таким образом.

2. Вы всегда можете написать свой алгоритм сортировки. То, что вы описываете, звучит как пузырьковая сортировка, ужасно неэффективный (но простой) алгоритм. std::sort выполняется очень быстро, и, по крайней мере, таким образом вам не придется изобретать велосипед.

3. я пытаюсь использовать std:: sort, просто не могу разобраться. Как мне это вызвать и что это за сортировка и откуда он знает, что это за сортировка.

4. Я думаю, мне может понадобиться помощь в определении того, как вычислить общее время гонки, тогда я мог бы просмотреть и отсортировать гонщиков с помощью этой функции сортировки, используя только время гонки. Можете ли вы указать мне правильное направление для вычисления общего времени гонки. У меня есть некоторый код для этого, но он работает неправильно, так что, очевидно, я делаю что-то не так. может быть, это в моем списке параметров?

5. std::sort использует концепцию, называемую «шаблоны». Если вы сортируете массив T , то std::sort будет использоваться оператор < , который сравнивает два T . Такой оператор определен по умолчанию для базовых типов, таких как int or float , а также для некоторых классов ( std::string например). Когда вы хотите отсортировать что-то еще, вам придется определить свой собственный оператор. Это то, что я делаю выше. Итак, поля вашей структуры не имеют правильных имен, поэтому трудно понять, что сравнивать, чтобы отсортировать их…

Ответ №3:

Как сказал Джон Цвинк, вы, вероятно, захотите использовать std::sort для выполнения сортировки. Лично я бы перегрузил operator>> и operator<< чтение и запись. Я бы также перегрузил operator< , чтобы выполнить сравнение.

При наличии всего этого ваш код верхнего уровня мог бы выглядеть примерно так:

 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"));
  

Учитывая ваши критерии (разделение мужчин и женщин), вы, вероятно, захотите рассматривать пол как основное поле, затем времена. Это сгруппирует всех мужчин вместе и всех женщин вместе (в порядке по вашему выбору).

Комментарии:

1. извини, Джерри. это немного выше моего понимания. Есть ли более простой способ сделать это?

2. Более простым способом было бы использовать другой язык программирования, такой как Python или bash.

3. вы можете сортировать структуры без использования динамических массивов или даже std::sort. Что было бы проще для меня, учитывая, что я еще не изучил эти методы, и что они не будут на моем выпускном экзамене. Если бы вы посмотрели на мой код, вы бы увидели, что у меня есть основные компоненты сортировки в, просто возникли проблемы с их реализацией. Как моя функция racerGender (), это правильно, или моя функция calcTotalTime (), это должно работать?? Спасибо, Джон.