C++ 从文件读取并通过矢量输出到控制台

C++ 从文件读取并通过矢量输出到控制台,c++,C++,我试图从这个文件中读取file.txt,其中包含奥运会期间参加跳远比赛的选手的内容 档案格式为[姓名][姓氏][国籍][距离] 这个档案里有40名选手。我正试图组织他们,让他们有一个运动员的指针向量,准确地说是40。然后动态地将它们分配到堆中。每个运动员都是向量中的一个对象 一旦将每个运动员对象输入到向量中,我希望通过for循环将向量的所有内容输出到控制台 然而,就目前的情况而言,在我的代码中,我确实有40个对象分配给了向量,但同一个对象被重复了40次。出于某种原因,最后一个对象也重复了两次 任

我试图从这个文件中读取file.txt,其中包含奥运会期间参加跳远比赛的选手的内容

档案格式为[姓名][姓氏][国籍][距离]

这个档案里有40名选手。我正试图组织他们,让他们有一个运动员的指针向量,准确地说是40。然后动态地将它们分配到堆中。每个运动员都是向量中的一个对象

一旦将每个运动员对象输入到向量中,我希望通过for循环将向量的所有内容输出到控制台

然而,就目前的情况而言,在我的代码中,我确实有40个对象分配给了向量,但同一个对象被重复了40次。出于某种原因,最后一个对象也重复了两次

任何帮助都将不胜感激!提前谢谢

测试.cpp

#include <iostream>
#include<fstream>
#include<vector>
#include<string>
#include "Person.h"
#include "Athlete.h"
using namespace std;

vector<Athlete*>  athletesList(40);

//overload the operator << to be used for printing the record Objects
ostream& operator<<(ostream& out, Athlete& a) {
    out << a.getFirstName() << " " << a.getLastName() << " " << a.getNationality() << " " << a.getDistance() << "\n";
    return out;
}

void readAthletesFromFile() {

    fstream athlethesFile;
    athlethesFile.open("file.txt");

    string tmpFirstName;
    string tmpLastName;
    string tmpNationality;
    string tmpDoubleDistance;

    while (!athlethesFile.eof()) {

        athlethesFile >> tmpFirstName;
        athlethesFile >> tmpLastName;
        athlethesFile >> tmpNationality;
        athlethesFile >> tmpDoubleDistance;

        double tmpDistance = stod(tmpDoubleDistance);

        for (int i = 0; i < 40; i++) {
            athletesList[i] = new Athlete(tmpFirstName, tmpLastName, tmpNationality, tmpDistance);
        }

        cout << *athletesList[0];



    }

}
int main()
{
    readAthletesFromFile();
    system("pause");

}
预期产出

Aleksandr Menkov Russia 8.09
Aleksandr Petrov Russia 7.89
Alyn Camara Germany 7.72
Arsen Sargsyan Armenia 7.62
Boleslav Skhirtladze Georgia 7.26
Christian Reif Germany 7.92
Christopher Tomlinson Great_Britain 8.06
Damar Forbes Jamaica 7.79
Eusebio Caceres Spain 7.92
George Kitchens United_States 6.84
Godfrey Khotso-Mokoena South_Africa 8.02
Greg Rutherford Great_Britain 8.08
Henry Frayne Australia 7.95
Ignisious Gaisah Ghana 7.79
Li Jinzhe China 7.77
Lin Ching-Hsuan-Taipei China 7.38
Louis Tsatoumas Greece 7.53
Luis Rivera Mexico 7.42
Marcos Chuva Portugal 7.55
Marquise Goodwin United_States 8.11
Mauro-Vinicius da-Silva Brazil 8.11
Michel Torneus Sweden 8.03
Mitchell Watt Australia 7.99
Mohamed Fathalla-Difallah Egypt 7.08
Mohammad Arzandeh Iran 7.84
Ndiss Kaba-Badji Senegal 7.66
Povilas Mykolaitis Lithuania 7.61
Raymond Higgs Bahamas 7.76
Roman Novotny Czech-Republic 6.96
Salim Sdiri France 7.71
Sebastian Bayer Germany 7.92
Sergey Morgunov Russia 7.87
Stanley Gbagbeke Nigeria 7.59
Stepan Wagner Czech-Republic 7.5
Supanara Sukhasvasti Thailand 7.38
Tyrone Smith Bermuda 7.97
Vardan Pahlevanyan Armenia 6.55
Viktor Kuznyetsov Ukraine 7.5
Will Claye United_States 7.99
Zhang Xiaoyi China 7.25
Ex: *athletesList[0] = Aleksandr Menkov Russia 8.09
    *athletesList[10]= Godfrey Khotso-Mokoena South_Africa 8.02
Ex: *athletesList[0] = 
Aleksandr Menkov Russia 8.09
Aleksandr Petrov Russia 7.89
Alyn Camara Germany 7.72
Arsen Sargsyan Armenia 7.62
Boleslav Skhirtladze Georgia 7.26
Christian Reif Germany 7.92
Christopher Tomlinson Great_Britain 8.06
Damar Forbes Jamaica 7.79
Eusebio Caceres Spain 7.92
George Kitchens United_States 6.84
Godfrey Khotso-Mokoena South_Africa 8.02
Greg Rutherford Great_Britain 8.08
Henry Frayne Australia 7.95
Ignisious Gaisah Ghana 7.79
Li Jinzhe China 7.77
Lin Ching-Hsuan-Taipei China 7.38
Louis Tsatoumas Greece 7.53
Luis Rivera Mexico 7.42
Marcos Chuva Portugal 7.55
Marquise Goodwin United_States 8.11
Mauro-Vinicius da-Silva Brazil 8.11
Michel Torneus Sweden 8.03
Mitchell Watt Australia 7.99
Mohamed Fathalla-Difallah Egypt 7.08
Mohammad Arzandeh Iran 7.84
Ndiss Kaba-Badji Senegal 7.66
Povilas Mykolaitis Lithuania 7.61
Raymond Higgs Bahamas 7.76
Roman Novotny Czech-Republic 6.96
Salim Sdiri France 7.71
Sebastian Bayer Germany 7.92
Sergey Morgunov Russia 7.87
Stanley Gbagbeke Nigeria 7.59
Stepan Wagner Czech-Republic 7.5
Supanara Sukhasvasti Thailand 7.38
Tyrone Smith Bermuda 7.97
Vardan Pahlevanyan Armenia 6.55
Viktor Kuznyetsov Ukraine 7.5
Will Claye United_States 7.99
Zhang Xiaoyi China 7.25
Zhang Xiaoyi China 7.25

电流输出

Aleksandr Menkov Russia 8.09
Aleksandr Petrov Russia 7.89
Alyn Camara Germany 7.72
Arsen Sargsyan Armenia 7.62
Boleslav Skhirtladze Georgia 7.26
Christian Reif Germany 7.92
Christopher Tomlinson Great_Britain 8.06
Damar Forbes Jamaica 7.79
Eusebio Caceres Spain 7.92
George Kitchens United_States 6.84
Godfrey Khotso-Mokoena South_Africa 8.02
Greg Rutherford Great_Britain 8.08
Henry Frayne Australia 7.95
Ignisious Gaisah Ghana 7.79
Li Jinzhe China 7.77
Lin Ching-Hsuan-Taipei China 7.38
Louis Tsatoumas Greece 7.53
Luis Rivera Mexico 7.42
Marcos Chuva Portugal 7.55
Marquise Goodwin United_States 8.11
Mauro-Vinicius da-Silva Brazil 8.11
Michel Torneus Sweden 8.03
Mitchell Watt Australia 7.99
Mohamed Fathalla-Difallah Egypt 7.08
Mohammad Arzandeh Iran 7.84
Ndiss Kaba-Badji Senegal 7.66
Povilas Mykolaitis Lithuania 7.61
Raymond Higgs Bahamas 7.76
Roman Novotny Czech-Republic 6.96
Salim Sdiri France 7.71
Sebastian Bayer Germany 7.92
Sergey Morgunov Russia 7.87
Stanley Gbagbeke Nigeria 7.59
Stepan Wagner Czech-Republic 7.5
Supanara Sukhasvasti Thailand 7.38
Tyrone Smith Bermuda 7.97
Vardan Pahlevanyan Armenia 6.55
Viktor Kuznyetsov Ukraine 7.5
Will Claye United_States 7.99
Zhang Xiaoyi China 7.25
Ex: *athletesList[0] = Aleksandr Menkov Russia 8.09
    *athletesList[10]= Godfrey Khotso-Mokoena South_Africa 8.02
Ex: *athletesList[0] = 
Aleksandr Menkov Russia 8.09
Aleksandr Petrov Russia 7.89
Alyn Camara Germany 7.72
Arsen Sargsyan Armenia 7.62
Boleslav Skhirtladze Georgia 7.26
Christian Reif Germany 7.92
Christopher Tomlinson Great_Britain 8.06
Damar Forbes Jamaica 7.79
Eusebio Caceres Spain 7.92
George Kitchens United_States 6.84
Godfrey Khotso-Mokoena South_Africa 8.02
Greg Rutherford Great_Britain 8.08
Henry Frayne Australia 7.95
Ignisious Gaisah Ghana 7.79
Li Jinzhe China 7.77
Lin Ching-Hsuan-Taipei China 7.38
Louis Tsatoumas Greece 7.53
Luis Rivera Mexico 7.42
Marcos Chuva Portugal 7.55
Marquise Goodwin United_States 8.11
Mauro-Vinicius da-Silva Brazil 8.11
Michel Torneus Sweden 8.03
Mitchell Watt Australia 7.99
Mohamed Fathalla-Difallah Egypt 7.08
Mohammad Arzandeh Iran 7.84
Ndiss Kaba-Badji Senegal 7.66
Povilas Mykolaitis Lithuania 7.61
Raymond Higgs Bahamas 7.76
Roman Novotny Czech-Republic 6.96
Salim Sdiri France 7.71
Sebastian Bayer Germany 7.92
Sergey Morgunov Russia 7.87
Stanley Gbagbeke Nigeria 7.59
Stepan Wagner Czech-Republic 7.5
Supanara Sukhasvasti Thailand 7.38
Tyrone Smith Bermuda 7.97
Vardan Pahlevanyan Armenia 6.55
Viktor Kuznyetsov Ukraine 7.5
Will Claye United_States 7.99
Zhang Xiaoyi China 7.25
Zhang Xiaoyi China 7.25

  • 动态分配内存。您不需要将它与STL容器结合使用。容器分配和管理堆上的内存
  • for循环不是必需的。对于您读取的每个元素,您将使用上次读取的元素覆盖所有元素
  • 为读取的每个元素打印向量中的第一个元素:

    改变

    cout << athletesList[0];
    
    因为
    eof
    是在您尝试读取后设置的,但失败。您必须在读取后检查读取是否成功

  • 如果不使用Person.h,请不要将其包括在内

  • 您应该避免使用
    system()
    。通常它不便于携带

在当前代码中,循环读取40个元素。在每个循环迭代中,为该向量分配40个元素。这意味着为1600个元素分配内存。你不能把它清理干净。这是一个严重的内存泄漏

#include "Athlete.h"
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
using std::cerr;
using std::cout;
using std::fstream;
using std::ostream;
using std::string;
using std::vector;

//overload the operator << to be used for printing the record Objects
ostream& operator<<(ostream& out, Athlete& a) {
    out << a.getFirstName() << " " << a.getLastName() << " " << a.getNationality() << " " << a.getDistance() << "\n";
    return out;
}

auto readAthletesFromFile() {
    vector<Athlete> athletesList;
    athletesList.reserve(40);

    fstream athlethesFile("file.txt");

    if (!athlethesFile) {
        cerr << "Could not open file\n";
        return athletesList;
    }

    string tmpFirstName;
    string tmpLastName;
    string tmpNationality;
    string tmpDoubleDistance;

    while (true) {
        athlethesFile >> tmpFirstName;
        athlethesFile >> tmpLastName;
        athlethesFile >> tmpNationality;
        athlethesFile >> tmpDoubleDistance;

        if (!athlethesFile) break;

        auto tmpDistance = stod(tmpDoubleDistance);
        athletesList.emplace_back(tmpFirstName, tmpLastName, tmpNationality, tmpDistance);

        //cout << athletesList.back();
    }
    return athletesList;
}

int main() {
    auto athletesList = readAthletesFromFile();
    cout << athletesList[9];
}
#包括“运动员.h”
#包括
#包括
#包括
#包括
使用std::cerr;
使用std::cout;
使用std::fstream;
使用std::ostream;
使用std::string;
使用std::vector;

//超负荷操作员我想假设@Thomas Sablik一开始的方向是正确的,但至少在我看来,他有点丢了球,可以这么说。我特别认为这一部分:

//overload the operator << to be used for printing the record Objects
ostream& operator<<(ostream& out, Athlete& a) {
    out << a.getFirstName() << " " << a.getLastName() << " " << a.getNationality() << " " << a.getDistance() << "\n";
    return out;
}
使用它,我们可以将几乎所有的内存管理留给标准库。事实上,可能根本不需要
readAthletesFromFile
。在文件中读取会变成这样:

std::ifstream input("file.txt");
std::vector<Athlete> list{std::istream_iterator<Athlete>(input), {}};

您应该阅读以解决第二个问题(“由于某种原因,最后一个对象也被重复了两次”),为什么要使用
vector athletesList(40)而不是
向量athletesList(40)。在哪里清理动态分配的内存?为什么要用
将同一矢量元素打印40次?无法将while从while(!athlethesFile.eof())更改为while(!athlethesFile)删除for循环并使用athleteslist.push_返回(新运动员(…)。这就是我能想到的。希望有帮助。@octopus实际上更好,但如果输入e后读取失败。G姓氏,这样会产生一个不完整的运动员…@octopus将
而(!athlethesFile.eof())
更改为
而(!athlethesFile)
不会改变问题。在这两种情况下,您都会读取并存储一个无效条目。eof检查仍然无效。如果在未设置eof的情况下发生IO错误怎么办?如果(!file)
检查
,也会捕捉到这一点。除此之外,它非常接近我自己会提出的建议…@Aconcagua好的,我把它修好了。嗯。。。也许我很挑剔,但如果一个使用STL容器,一个使用动态内存分配,不是吗?也许是因为我的背景,但如果我听到这句话,STL也会被删除(只允许静态或本地存储——微控制器上通常是这样)…@Aconcagua但你是对的,编译器也很挑剔。我重新制定了它。
class Athlete {
public:
    friend std::ostream& operator<<(std::ostream& out, Athlete const& a) {
        out << a.firstName << " " << a.lastName << " " << a.nationality << " " << a.distance << "\n";
        return out;
    }

    friend std::istream &operator>>(std::istream &in, Athlete &a) { 
        in >> a.firstName >> a.lastName >> a.nationality >> a.distance;
        return in;
    }

    bool operator<(Athlete const &other) const { 
        return distance < other.distance;
    }

private:

    std::string firstName, lastName, nationality;
    double distance;
};

int main() {
    std::ifstream in("file.txt");
    std::vector<Athlete> list{std::istream_iterator<Athlete>(in), {}};

    std::partial_sort(list.begin(), list.end()-5, list.end());
    std::copy(list.end()-5, list.end(), std::ostream_iterator<Athlete>(std::cout, ""));
}
Mauro-Vinicius da-Silva Brazil 8.11
Marquise Goodwin United_States 8.11
Aleksandr Menkov Russia 8.09
Greg Rutherford Great_Britain 8.08
Christopher Tomlinson Great_Britain 8.06