Очевидно, что мы должны реализовать используемые нами функции. Соблазнительно, конечно, сэкономить бумагу и спасти дерево, предоставив читателям самостоятельно решить эту задачу, но мы решили, что пример должен быть полным.
Конструктор класса Mail_file открывает файл и создает векторы lines и m.
Mail_file::Mail_file(const string& n)
// открывает файл с именем "n"
// считывает строки из файла "n" в вектор lines // находит сообщения в векторе lines и помещает их в вектор m, // для простоты предполагая, что каждое сообщение заканчивается // строкой " " line
{
ifstream in(n.c_str()); // открываем файл if (!in) {
cerr << "нет " << n << '\n';
exit(1); // прекращаем выполнение программы
}
string s;
while (getline(in,s)) lines.push_back(s); // создаем вектор
// строк
Line_iter first = lines.begin(); // создаем вектор сообщений for (Line_iter p = lines.begin(); p!=lines.end(); ++p) {
if (*p == " ") { // конец сообщения
m.push_back(Message(first,p));
first = p+i; // строка не является частью
// сообщения
}
}
}
Обработка ошибок носит слишком элементарный характер. Если бы писали эту программу для своих друзей, то постарались бы сделать ее лучше.
Что значит “более хорошая обработка ошибок”? Измените конструктор класса Mail_file так, чтобы он реагировал на ошибки форматирования, связанные с использованием строки “ ”.
Функции find_from_addr() и find_subject() не имеют конкретного содержания, пока мы не выясним, как идентифицировать информацию в файле (используя регулярные выражения.
int is_prefix(const string& s, const string& p)
// Является ли строка p первой частью строки 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 "";
}
|