简体   繁体   English

将文件中的数据读取到结构中,对数据进行排序并写入文件

[英]Reading data from a file into a struct, sorting the data and writing to a file

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. 该项目将从文件[“ racers2011.txt”]中读取数据到一个结构中,对雄性的比赛时间进行排序,对雌性的比赛时间进行排序。 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;
*/
    }
}

Use std::sort . 使用std :: sort Saying much more would give it away, and I imagine this is homework. 多说些什么就可以了,我想这是家庭作业。

As John Zwinck said, you probably want to use std::sort to do the sorting. 正如John Zwinck所说,您可能想使用std::sort进行排序。 Personally, I'd overload operator>> and operator<< to the reading and writing. 就个人而言,我会在读取和写入时重载operator>>operator<< I'd also overload operator< to do the comparison. 我也将重载operator<进行比较。

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). 这会将所有雄性组合在一起,并将所有雌性组合在一起(按您选择的顺序)。

std::sort is a very efficient sorting function that is part of the C++ standard, in the header algorithm . std::sort是一个非常有效的排序函数,属于标头algorithm中的C ++标准。

std::sort uses the concept of "iterators". std::sort使用“迭代器”的概念。 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[ ). 在C ++中,任何序列都可以表示为一对迭代器:一个指向第一个元素,第二个指向最后一个元素之后的一个点(因此[begin, end[ )。 This can easily be seen in arrays: for an array a with size N , a[N] is not part of the array. 这在数组中很容易看到:对于大小为N的数组aa[N]不属于数组。 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:

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

The above line can be read as "sort the elements in the sequence delimited by racers and racers + MAX ". 上一行可以理解为“按racersracers + 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. 如果您使用标准容器,例如std::vector ,则将使用向量的begin()end()方法来获取适当的迭代器。

Now, std::sort compares each element two-by-two using a comparing function. 现在, std::sort使用比较函数std::sort每个元素进行两三比较。 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: 在我们的例子中,对于Racer_struct重载<就足够了:

// 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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM