Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 6a4f88d

Browse files
committed
Exercise 23.1; Exercise 23.2
1 parent c19a72e commit 6a4f88d

File tree

6 files changed

+491
-0
lines changed

6 files changed

+491
-0
lines changed

‎Chapter_23/C23_Exercise_23.1.cpp

Lines changed: 170 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,170 @@
1+
/* Exercise 23.1 */
2+
3+
#include<iostream>
4+
#include<istream>
5+
#include<fstream>
6+
#include<sstream>
7+
#include<iomanip>
8+
#include<string>
9+
#include<vector>
10+
#include<map>
11+
#include"C23_Exercise_23.1.h"
12+
13+
using namespace std;
14+
15+
inline void error(string s) { throw runtime_error(s); }
16+
inline void error(const string& s, const string& s2) { error(s + s2); }
17+
inline void error(const string& s, int i) { ostringstream os; os << s << ": " << i; error(os.str()); }
18+
inline void keep_window_open() { char ch; cin >> ch; }
19+
20+
int main()
21+
{
22+
enum Action {
23+
EXIT = -1, PRINTACTIONLIST,
24+
CASE1, CASE2, CASE3, CASE4, CASE5
25+
};
26+
const string actionList = "\tList of actions:\n"
27+
" (1) Sender, (2) Recipient\n"
28+
" (-1) Exit, (0) Print the list of actions\n";
29+
cout << actionList;
30+
int action;
31+
bool cond{ true };
32+
while (cond) try {
33+
cout << "\nPlease enter the action: ";
34+
if (!(cin >> action)) { ClearInput(cin); error("Error. Incorrect input"); }
35+
char ch;
36+
cin.get(ch);
37+
switch (action) {
38+
case CASE1: {
39+
cout << endl;
40+
Mail_file mfile{ "C23_Exercise_23.1_mail.txt" }; // initialize mfile from a file
41+
// first gather messages from each sender together in a multimap:
42+
multimap<string, const Message*> sender;
43+
for (const auto& m : mfile) {
44+
string s;
45+
if (find_from_addr(&m, s)) {
46+
sender.insert(make_pair(s, &m));
47+
}
48+
}
49+
// now iterate through the multimap
50+
// and extract the subjects of John Doe’s messages:
51+
auto pp = sender.equal_range("John Doe <jdoe@machine.example>");
52+
for (auto p = pp.first; p != pp.second; ++p) {
53+
cout << find_subject(p->second) << '\n';
54+
}
55+
56+
cout << vsp_2;
57+
break;
58+
}
59+
case CASE2: {
60+
cout << endl;
61+
Mail_file mfile{ "C23_Exercise_23.1_mail.txt" };
62+
multimap<string, const Message*> recipient;
63+
for (const auto& m : mfile) {
64+
string s;
65+
if (find_to_addr(&m, s)) {
66+
recipient.insert(make_pair(s, &m));
67+
}
68+
}
69+
// now iterate through the multimap
70+
// and extract the subjects of John Doe’s messages:
71+
auto pp = recipient.equal_range("Chester Cole <ccole@example.net>");
72+
int messageNum = 0;
73+
for (auto p = pp.first; p != pp.second; ++p) {
74+
++messageNum;
75+
cout << sp_2 << "Message #" << messageNum << endl;
76+
for (auto it = p->second->begin(); it != p->second->end(); ++it) {
77+
cout << sp_4 << *it << endl;
78+
}
79+
cout << endl;
80+
}
81+
82+
cout << vsp_2;
83+
break;
84+
}
85+
case PRINTACTIONLIST:
86+
cout << actionList;
87+
break;
88+
case EXIT:
89+
cond = false;
90+
break;
91+
default:
92+
error("Error. Incorrect action number");
93+
break;
94+
}
95+
}
96+
catch (runtime_error& e) {
97+
cerr << e.what() << endl;
98+
}
99+
catch (...) {
100+
cerr << "Error. Exception\n";
101+
return 1;
102+
}
103+
return 0;
104+
}
105+
106+
void ClearInput(istream& is)
107+
{
108+
is.clear();
109+
is.ignore(numeric_limits<streamsize>::max(), '\n');
110+
}
111+
112+
Mail_file::Mail_file(const string& n)
113+
// open file named n
114+
// read the lines from n into lines
115+
// find the messages in the lines and compose them in m
116+
// for simplicity assume every message is ended by a ---- line
117+
{
118+
ifstream in{ n }; // open the file
119+
if (!in) {
120+
cerr << "no " << n << '\n';
121+
exit(1); // terminate the program
122+
}
123+
for (string s; getline(in, s); ) { // build the vector of lines
124+
lines.push_back(s);
125+
}
126+
auto first = lines.begin(); // build the vector of Messages
127+
for (auto p = lines.begin(); p != lines.end(); ++p) {
128+
if (*p == "----") { // end of message
129+
m.push_back(Message(first, p));
130+
first = p + 1; // ---- not part of message
131+
}
132+
}
133+
}
134+
135+
int is_prefix(const string& s, const string& p) // is p the first part of s?
136+
{
137+
int n = p.size();
138+
if (string(s, 0, n) == p) return n;
139+
return 0;
140+
}
141+
142+
bool find_from_addr(const Message* m, string& s)
143+
{
144+
for (const auto& x : *m) {
145+
if (int n = is_prefix(x, "From: ")) {
146+
s = string(x, n);
147+
return true;
148+
}
149+
}
150+
return false;
151+
}
152+
153+
bool find_to_addr(const Message* m, string& s)
154+
{
155+
for (const auto& x : *m) {
156+
if (int n = is_prefix(x, "To: ")) {
157+
s = string(x, n);
158+
return true;
159+
}
160+
}
161+
return false;
162+
}
163+
164+
string find_subject(const Message* m)
165+
{
166+
for (const auto& x : *m) {
167+
if (int n = is_prefix(x, "Subject: ")) return string(x, n);
168+
}
169+
return "";
170+
}

‎Chapter_23/C23_Exercise_23.1.h

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
/* Exercise 23.1 */
2+
3+
using namespace std;
4+
5+
const char* sp_2 = " ";
6+
const char* sp_4 = " ";
7+
const char* sp_6 = " ";
8+
const char* sp_8 = " ";
9+
const char* vsp_2 = "\n\n";
10+
const char* vsp_3 = "\n\n\n";
11+
const char* vsp_4 = "\n\n\n\n";
12+
13+
void ClearInput(istream& is);
14+
15+
using Line_iter = vector<string>::const_iterator;
16+
17+
class Message { // a Message points to the first and the last lines of a message
18+
Line_iter first;
19+
Line_iter last;
20+
public:
21+
Message(Line_iter p1, Line_iter p2) :first{ p1 }, last{ p2 } { }
22+
Line_iter begin() const { return first; }
23+
Line_iter end() const { return last; }
24+
//...
25+
};
26+
27+
using Mess_iter = vector<Message>::const_iterator;
28+
29+
struct Mail_file { // a Mail_file holds all the lines from a file
30+
// and simplifies access to messages
31+
string name; // file name
32+
vector<string> lines; // the lines in order
33+
vector<Message> m; // Messages in order
34+
Mail_file(const string& n); // read file n into lines
35+
Mess_iter begin() const { return m.begin(); }
36+
Mess_iter end() const { return m.end(); }
37+
};
38+
39+
// find the name of the sender in a Message;
40+
// return true if found
41+
// if found, place the sender’s name in s:
42+
bool find_from_addr(const Message* m, string& s);
43+
bool find_to_addr(const Message* m, string& s);
44+
// return the subject of the Message, if any, otherwise "":
45+
string find_subject(const Message* m);

‎Chapter_23/C23_Exercise_23.1_mail.txt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
From: John Doe <jdoe@machine.example>
2+
To: Mary Smith <mary@example.net>
3+
Subject: Saying Hello
4+
Date: 1997年11月21日 09:55:06 -0600
5+
Message-ID: <1234@local.machine.example>
6+
7+
This is a message just to say hello.
8+
So, "Hello".
9+
----
10+
From: Mary Smith <mary@example.net>
11+
To: John Doe <jdoe@machine.example>
12+
Reply-To: "Mary Smith: Personal Account" <smith@home.example>
13+
Subject: Re: Saying Hello
14+
Date: 1997年11月21日 10:01:10 -0600
15+
Message-ID: <3456@example.net>
16+
In-Reply-To: <1234@local.machine.example>
17+
References: <1234@local.machine.example>
18+
19+
This is a reply to your hello.
20+
----
21+
To: "Mary Smith: Personal Account" <smith@home.example>
22+
From: John Doe <jdoe@machine.example>
23+
Subject: Re: Saying Hello
24+
Date: 1997年11月21日 11:00:00 -0600
25+
Message-ID: <abcd.1234@local.machine.tld>
26+
In-Reply-To: <3456@example.net>
27+
References: <1234@local.machine.example> <3456@example.net>
28+
29+
This is a reply to your reply.
30+
----
31+
From: John Doe <jdoe@machine.example>
32+
To: Chester Cole <ccole@example.net>
33+
Subject: Hello to Chester
34+
Date: 1997年11月23日 09:00:06 -0600
35+
Message-ID: <5555@local.machine.example>
36+
37+
One more "Hello".
38+
----
39+
From: John Doe <jdoe@machine.example>
40+
To: Eli Harris <eharris@example.net>
41+
Subject: Hello to Eli
42+
Date: 1997年11月23日 09:01:15 -0600
43+
Message-ID: <6666@local.machine.example>
44+
45+
One more "Hello".
46+
----
47+
From: Mary Smith <mary@example.net>
48+
To: Chester Cole <ccole@example.net>
49+
Subject: Business proposal
50+
Date: 1997年11月25日 10:36:19 -0600
51+
Message-ID: <3478@example.net>
52+
53+
Good morning, Chester
54+
I have a business proposal for you
55+
----

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /