“电子邮件”阅读器 - 奇怪的迭代器问题

时间:2009-09-06 01:32:09

标签: c++ iterator

这个程序读取“电子邮件”(实际上只是一个像电子邮件一样构建的.txt文件)并用它做各种事情(在地图中存储数据并操纵它)。

但是,我遇到了一个不寻常的问题,即根据搜索主题输出电子邮件的“消息”。首先 - 这是代码(您可以忽略除end和find_message函数之外的所有内容。)

#include <string>
#include <vector>
#include <map>
#include <fstream>
#include <iostream>
using namespace std;

typedef vector<string>::const_iterator Line_iter;
class Message { // a Message points to the first and the 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; }
    //...
};

typedef vector<Message>::const_iterator Mess_iter;

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(); }
};

Mail_file::Mail_file(const string& n)
    // open file named "n"
    // read the lines from "n" into "lines"
    // find the messages in the lines and compose them in m
    // for simplicity assume every message is ended by a "----" line
{
    ifstream in(n.c_str()); // open the file
    if (!in) {
        cerr << "no " << n << '\n';
        exit(1);    // terminate the program
    }

    string s;
    while (getline(in,s)) lines.push_back(s);   // build the vector of lines

    Line_iter first = lines.begin();    // build the vector of Messages
    for (Line_iter p = lines.begin(); p!=lines.end(); ++p) {
        if (*p == "----") {  // end of message
            m.push_back(Message(first,p));
            first = p+1;    // ---- not part of message
        }
    }
}

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 (Line_iter p = m->begin(); p!=m->end(); ++p)
        if (int n = is_prefix(*p, "From: ")) {
            s = string(*p, n);
            return true;
        }
    return false;
}

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 "";
}

string find_message(const Message* m)
{
    for (Line_iter p = m->begin(); p!=m->end(); ++p)
        if (int n = is_prefix(*p, "Subject: ")) {
            p += 2;
            return string(*p);
        }
    return "";
}

int main()
{
    Mail_file mfile("my-mail-file.txt");    // initialize mfile from a file

    // first gather messages from each sender together in a multimap

    multimap<string, const Message*> sender;
    multimap<string, const Message*> subject;

    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));
        subject.insert(make_pair(find_subject(&m), &m));
    }

    // now iterate through the multimap and extract the subjects of John Doe's messages
    typedef multimap<string, const Message*>::const_iterator MCI;
    pair<MCI,MCI> pp = sender.equal_range("John Doe");
    for (MCI p = pp.first; p != pp.second; ++p)
        cout << find_subject(p->second) << '\n';

    string subject_search;
    cout << '\n' << "Enter a subject to search for: ";
    cin >> subject_search;
    pair<MCI, MCI> sub = subject.equal_range(subject_search);
    for (MCI p = sub.first; p != sub.second; ++p)
        cout << '\n' << find_message(p->second);
}

由于某种原因,消息输出输出任何内容。我做了一些基本测试并尝试了

cout << find_message(sub.first->second) << endl;

只是为了查看该功能是否无效并输出消息正常。所以很明显for循环有问题,即使p被分配给同样的迭代器,它也不输出任何东西。感谢任何帮助。谢谢。

P.S。显然find_message()函数还没有完成,只输出带有幻数的第一行,但请耐心等待。

1 个答案:

答案 0 :(得分:3)

对我来说很好。您是否正在尝试搜索其中包含空格的主题?我相信声明

cin >> subject_search;

只读取第一个空白字符的字符串。也许你想要

getline(cin,subject_search);