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 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
|
// C23TryThis.cpp
#include<iostream>
#include<fstream>
#include<sstream>
#include<string>
#include<vector>
#include <map>
using namespace std;
typedef vector<string>::const_iterator Line_iter;
class Message { // a Message points to the first and last lines of a message
Line_iter first;
Line_iter last;
public:
Message(Line_iter p1, Line_iter p2) : first{ p1 }, last{ p2 } {}
Line_iter begin() const { return first; }
Line_iter end() const { return last; }
//...
};
using Mess_iter = vector<Message>::const_iterator;
struct Mail_file { // a Mail_file holds all the lines from a file
// and simplifies access to messages
string name; // file name
vector<string> lines; // the lines in order
vector<Message> m; // Messages in order
Mail_file(const string& n); // read file n into lines
Mess_iter begin() const { return m.begin(); }
Mess_iter end() const { return m.end(); }
};
bool find_from_addr(const Message* m, string& s);
string find_subject(const Message* m);
int main()
{
Mail_file mfile{ "my-mail-file.txt" };
// first gather messages from each sender together in a multimap:
multimap<string, const Message*> sender;
for (const auto& m : mfile) {
string s;
if (find_from_addr(&m, s))
sender.insert(make_pair(s, &m));
}
// now iterate through the multimap
// and extract the subject of John Doe's messages:
auto pp = sender.equal_range("John Doe <jdoe@machine.examples>");
for (auto p = pp.first; p != pp.second; ++p)
cout << find_subject(p->second) << '\n';
}
int is_prefix(const string& s, const string& p)
// is p the first part of s?
{
int n = p.size();
if (string(s, 0, n) == p) return n;
return 0;
}
bool find_from_addr(const Message* m, string& s)
{
for (const auto& x : m) //Error: this range based 'for' statement requires a suitable "begin" function and none was found
if (int n = is_prefix(x, "From: ")) {
s = string(x, n);
return true;
}
return false;
}
string find_subject(const Message* m) m)
{
for (const auto& x : m) //Error: expected a declaration
if (int n = is_prefix(x, "Subject: ")) return string(x, n);
return "";
}
Mail_file::Mail_file(const string& n)
{
ifstream in{ n };
if (!in) {
cerr << "no " << n << '\n';
exit(1);
}
for (string s; getline(in, s);)
lines.push_back(s);
auto first = lines.begin();
for (auto p = lines.begin(); p != lines.end(); ++p) {
if (*p == "----") {
m.push_back(Message(first, p));
first = p + 1;
}
}
}
|