1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66
|
#include <iostream>
#include <fstream>
#include <queue>
#include <tuple>
class alert {
public:
alert() = default; // don't leave functions undefined;
alert(char c, std::string i, int p, std::string d)
: cat(c), id(i) // use initializer lists
, pri(p), desc(d) {} // no definition needed
// compute the result instead of caching it -- otherwise
// if cat is changed, catPri would not update.
int getCatPri() const {
if (cat == 'M') return 3;
if (cat == 'C') return 2;
else return 1;
}
int getPri() const { return pri; }
char getCat() const { return cat; }
std::string getID() const { return id; }
std::string getDe() const { return desc; }
friend std::istream& operator>>(std::istream& s, alert& a) {
s >> a.cat >> std::ws >> a.id >> std::ws >> a.pri >> std::ws;
return getline(s, a.desc);
}
private:
char cat;
std::string id;
int pri;
std::string desc;
};
// replaces alert::display()
// it can be implemented in terms of the public interface --
// it doesn't need direct access to the members of alert.
std::ostream& operator<<(std::ostream& s, alert const& a) {
return s << a.getCat() << ' ' << a.getID() << ' '
<< a.getPri() << ' ' << a.getDe();
}
// replaces the compare class
// the result of forward_as_tuple is compared in lexicographic order.
// This is a tidy way to compare things correctly.
bool operator<(alert const& a, alert const& b) {
return std::forward_as_tuple(a.getCatPri(), a.getPri()) <
std::forward_as_tuple(b.getCatPri(), b.getPri());
}
int main (int argc, char** argv){
if (argc != 2) {
std::cerr << "Usage: " << argv[0] << "inFileName\n";
return -1;
}
std::ifstream data{argv[1]};
std::priority_queue<alert> qu;
for (alert a; data >> a; ) qu.push(a);
std::cout << qu.size() << '\n';
for(; qu.size(); qu.pop()) std::cout << qu.top() << '\n';
}
|