23.4 map在文本处理中的应用
2019-07-27 本文已影响0人
Jianbaozi
书中给的实现细节编译报错,参考了http://www.stroustrup.com/Programming/的代码
#include<iostream>
#include<vector>
#include<string>
#include<map>
#include<fstream>
using namespace std;
typedef vector<string>::const_iterator Line_iter;
class 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 {
string name;
vector<string>lines;
vector<Message> m;
Mail_file(const string& n);
Mess_iter begin()const { return m.begin(); }
Mess_iter end()const { return m.end(); }
};
Mail_file::Mail_file(const string& n) {
ifstream in(n.c_str());
if (!in) {
cerr << "error open file!" << endl;
exit(1);
}
cout << "Open file success!" << endl;
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;
}
}
}
int is_prefix(const string& s, const string &p) {
int n = p.size();
if (string(s, 0, n) == p)
return n;
return 0;
}
//可以将函数用于条件判断,同时修改参数s的内容
bool find_from_addr(const Message*m, string &s) {
for (Line_iter p = m->begin(); p != m->end(); ++p)
if (int n = is_prefix(*p, "From: ")) {
s = string(*p, n);//构造string(s[n].....s[s.size()-1])
return true;
}
return false;
}
/* !!!一个错误示范,for循环内的if语句作用域问题
string find_subject(const Message& m) {
for (Line_iter p = m.begin(); p != m.end(); ++p) {
if (int n = is_prefix(*p, "Subject: "))
return string(*p, n);
return "null";
}
}
*/
string find_subject(const Message& m){
for (Line_iter p = m.begin(); p != m.end(); ++p)
if (int n = is_prefix(*p, "Subject: ")) return string(*p, n);
return "null"; //对应主题为空或者不存在的情况
}
int main() {
Mail_file mfile{ "D:/Workspace/cpp/Projects/mail.txt" };
multimap<string, const Message*>sender;
for (Mess_iter p = mfile.begin(); p != mfile.end(); ++p) {
const Message& m = *p;
string s;
if (find_from_addr(&m, s))
sender.insert(make_pair(s, &m));
}
for (auto &x : sender) {
cout <<"Mail begin:"<< *(x.second)->begin()
<< " Mail end:" << *(x.second)->end() << endl;
//输出multimap所有内容
}
typedef multimap<string, const Message*>::const_iterator mci;
pair<mci, mci> pp = sender.equal_range("John Doe <jdoe@machine.example>");
//multimap为有序容器,equal_range()返回找到的内容,范围为[first,second)
for (mci p = pp.first; p != pp.second; ++p)
cout <<"name:"<<(p->first)<<"Subject:"<<find_subject(*(p->second)) << endl;
//此处first,second是multimap的(关键字,值)
system("pause");
return 0;
}
测试文本
XXX
XXX
----
From: John Doe <jdoe@machine.example>
To: Mary Smith <marry@example.net>
Subject: Saying Hello
Date: Fri,21,Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message to say hello.
So,"Hello".
----
From: Joe Q <john.q@machine.example>
To: Mary Smith <marry@example.net>
Subject: Saying How are you
Date: Fri,21,Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message to say How are you.
So,"How are you".
----
From: John Doe <jdoe@machine.example>
To: Mary Smith <marry@example.net>
Subject: Saying Howdy
Date: Fri,21,Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message to say Howdy
So,"Howdy".
----
From: John Doe <jdoe@machine.example>
To: Mary Smith <marry@example.net>
Subject:
Date: Fri,21,Nov 1997 09:55:06 -0600
Message-ID: <1234@local.machine.example>
This is a message to say Good day.
So,"Good day".
----
----
输出结果:
Open file success!
Mail begin:From: Joe Q <john.q@machine.example> Mail end:----
Mail begin:From: John Doe <jdoe@machine.example> Mail end:----
Mail begin:From: John Doe <jdoe@machine.example> Mail end:----
Mail begin:From: John Doe <jdoe@machine.example> Mail end:----
==================================================================
name:John Doe <jdoe@machine.example>Subject:Saying Hello
name:John Doe <jdoe@machine.example>Subject:Saying Howdy
name:John Doe <jdoe@machine.example>Subject:null
请按任意键继续. . .