从文件写入读取类成员函数并在C ++中在控制台上打印?

时间:2018-12-04 18:10:21

标签: c++ oop vector cout

我有2个类,我从第二个类中创建了一个对象(我将文件名作为参数传递)。它应以以下格式打印包含以下数据的文件内容:

A.Yordanov 1234567819
S.Todorov 3456789120
D.Lazarov 2569789054
P.Pavlov 4329549823
M.Kalinova 2367892343
B.Georgiev 659045324

我已经重载了<<运算符,但是当我尝试cout << cty2时,即使将文件放在同一目录中,控制台上也没有任何显示吗?

// OOP_Homework.cpp : This file contains the 'main' function. Program execution begins and ends there.
//
#include <iostream>
#include <fstream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
using namespace std;
fstream f;
class CPerson {
    string name;
    string egn;
public:
    CPerson(string n, string e) {
        name = n;
        egn = e;
    }
    friend bool operator<(CPerson p1, CPerson p2) {
        if (p1.egn < p2.egn) {
            return true;
        }
        return false;
    }
    friend bool operator==(CPerson p1, CPerson p2) {
        if (p1.egn == p2.egn) {
            return true;
        }
        return false;
    }
    friend ostream& operator<< (ostream o, CPerson pn) {
        o << "Egn" << endl;
        o << pn.egn << endl;
        o << "Name:" << endl;
        o << pn.name << endl;
    }
    friend istream& operator>> (istream is, CPerson p) {
        is >> p.egn;
        is >> p.name;
        return is;
    }
    string getName() {
        return name;
    }
    string getEgn() {
        return egn;
    }
    void setName(string n) {
        name = n;
    }
    void setEgn(string e) {
        egn = e;
    }
};
class CCity {
    vector<CPerson> pr;
public:
    CCity(string fl) {
        f.open(fl, ios::out);
        string name = "", fn = "";
        while (!f.eof()) {
            //формата на данните във файла е във вида:
            //<име на студент> <факултетен номер>
            cin >> name >> fn;
            pr.push_back(CPerson(name, fn));
        }
        f.close();
    }
    //помощен getter за вектора  pr;
    vector<CPerson> getV() {
        return pr;
    }
    friend ostream& operator<<(ostream& os, CCity& psn) {
        vector<CPerson> ps = psn.getV();
        for (auto x = ps.begin(); x != ps.end(); x++) {
            os << x->getName() << endl;
            os << x->getEgn() << endl;
        }
        return os;
    }
    vector<CPerson> getDuplicate() {
        set<CPerson> temp;
        vector<CPerson> duplicates;
        for (auto i = pr.begin(); i != pr.end(); i++) {
            for (auto x : pr) {
                if (*i == x) {
                    temp.insert(*i);
                }
            }
        }
        for (auto j : temp) {
            duplicates.push_back(j);
        }
        temp.clear();
        //връщаме студентите с повтарящи се егн-та
        return duplicates;
    }
    void removeDuplicates() {
        sort(pr.begin(),pr.end());
        pr.erase(unique(pr.begin(), pr.end()));
    }
    void removeVector(vector<CPerson> ob) {
        for (auto i:ob) {
            for (auto x = pr.begin(); x != pr.end(); x++) {
                if (i == *x) {
                    pr.erase(x);
                }
            }
        }
    }
};
int main()
{
    CCity  cty2("persons.txt");
    //cout << cty1 << endl;
    cout << cty2 << endl;
    return 0;
}

1 个答案:

答案 0 :(得分:4)

operator<<的重载代码应为

friend ostream& operator<< (ostream &o, const CPerson &pn) {
    //                              ^   ^^^^^         ^

    o << "Egn" << endl;
    o << pn.egn << endl;
    o << "Name:" << endl;
    o << pn.name << endl;

    return o;  // since return type is ostream&
}

您应该通过引用传递流,并在使用完毕后将其返回。按引用传递可确保使用相同的流(与按值传递不同)。

要注意的另一件事是您的CPerson p函数参数。这些也应通过引用传递。使用operator<<,您的CPerson将不会被修改,因此我们可以将其保留为const

您可能还需要注意operator>>。同样,istream is应该是istream &is。使用CPerson p参数,您可以 对其进行修改,因此您肯定希望将其作为参考传递。

friend istream& operator>> (istream &is, CPerson &p) {
    //                              ^            ^

    is >> p.egn;
    is >> p.name;
    return is;
}

在其他重载中,您也应该使用const CPerson &p。此外,operator<operator==的重载不需要friend,因为它们不访问任何其他类的私有成员。因此,

bool operator<(const CPerson &p1, const CPerson &p2) {
    if (p1.egn < p2.egn) {
        return true;
    }
    return false;
}

bool operator==(const CPerson &p1, const CPerson &p2) {
    if (p1.egn == p2.egn) {
        return true;
    }
    return false;
}

您将习惯于通过引用传递类,因为它节省了空间(不必像传递值传递那样复制-构造该类的另一个实例)。因此,通过引用传递您的类在空间和性能方面都更加有效。