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
请按任意键继续. . .

上一篇下一篇

猜你喜欢

热点阅读