Читаем Программирование полностью

Каждый объект класса Document начинается с пустой строки: конструктор класса Document сначала создает пустую строку, а затем заполняет список строка за строкой.

Чтение и разделение на строки можно выполнить следующим образом:

istream& operator>>(istream& is, Document& d)

{

  char ch;

  while (is.get(ch)) {

    d.line.back().push_back(ch); // добавляем символ

    if (ch=='\n')

      d.line.push_back(Line());  // добавляем новую строку

  }

  if (d.line.back().size())

    d.line.push_back(Line());    // добавляем пустую строку

  return is;

}

Классы vector и list имеют функцию-член back(), возвращающую ссылку на последний элемент. Для ее использования вы должны быть уверены, что она действительно ссылается на последний элемент, — функцию back() нельзя применять к пустому контейнеру. Вот почему в соответствии с определением каждый объект класса Document должен содержать пустой объект класса Line. Обратите внимание на то, что мы храним каждый введенный символ, даже символы перехода на новую строку ('\n'). Хранение символов перехода на новую строку сильно упрощает дело, но при подсчете символов следует быть осторожным (простой подсчет символов будет учитывать пробелы и символы перехода на новую строку).

<p id="AutBody_Root382"><strong>20.6.2. Итерация</strong></p>

 Если бы документ хранился как объект класса vector, перемещаться по нему было бы просто. Как перемещать итератор по списку строк? Очевидно, что перемещаться по списку можно с помощью класса list::iterator. Однако, что, если мы хотим пройтись по символам один за другим, не беспокоясь о разбиении строки? Мы могли бы использовать итератор, специально разработанный для нашего класса Document.

class Text_iterator { // отслеживает позицию символа в строке

  list::iterator ln;

  Line::iterator pos;

public:

  // устанавливает итератор на позицию pp в ll-й строке

  Text_iterator(list::iterator ll, Line::iterator pp)

  :ln(ll), pos(pp) { }

  char& operator*() { return *pos; }

  Text_iterator& operator++();

  bool operator==(const Text_iterator& other) const

    { return ln==other.ln && pos==other.pos; }

  bool operator!=(const Text_iterator& other) const

    { return !(*this==other); }

};

Text_iterator& Text_iterator::operator++()

{

  if (pos==(*ln).end()) {

    ++ln; // переход на новую строку

    pos = (*ln).begin();

  }

  ++pos; // переход на новый символ

  return *this;

}

Для того чтобы класс Text_iterator стал полезным, необходимо снабдить класс Document традиционными функциями begin() и end().

struct Document {

  list line;

  Text_iterator begin() // первый символ первой строки

    { return Text_iterator(line.begin(),

    (*line.begin()).begin()); }

  Text_iterator end()   // за последним символом последней строки

    { return(line.end(), (*line.end()).end));}

};

Мы использовали любопытную конструкцию (*line.begin()).begin(), потому что хотим начинать перемещение итератора с позиции, на которую ссылается итератор line.begin(); в качестве альтернативы можно было бы использовать функцию line.begin()–>begin(), так как стандартные итераторы поддерживают операцию –>.

Теперь можем перемещаться по символам документа.

void print(Document& d)

{

  for (Text_iterator p = d.begin();

  p!=d.end(); ++p) cout << *p;

}

print(my_doc);

Представление документа в виде последовательности символов полезно по многим причинам, но обычно мы перемещаемся по документам, просматривая более специфичную информацию, чем символ. Например, рассмотрим фрагмент кода, удаляющий строку n.

void erase_line(Document& d, int n)

{

  if (n<0 || d.line.size()<=n) return; // игнорируем строки,

                                       // находящиеся

                                       // за пределами диапазона

Перейти на страницу:

Похожие книги

1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
1С: Управление торговлей 8.2
1С: Управление торговлей 8.2

Современные торговые предприятия предлагают своим клиентам широчайший ассортимент товаров, который исчисляется тысячами и десятками тысяч наименований. Причем многие позиции могут реализовываться на разных условиях: предоплата, отсрочка платежи, скидка, наценка, объем партии, и т.д. Клиенты зачастую делятся на категории – VIP-клиент, обычный клиент, постоянный клиент, мелкооптовый клиент, и т.д. Товарные позиции могут комплектоваться и разукомплектовываться, многие товары подлежат обязательной сертификации и гигиеническим исследованиям, некондиционные позиции необходимо списывать, на складах периодически должна проводиться инвентаризация, каждая компания должна иметь свою маркетинговую политику и т.д., вообщем – современное торговое предприятие представляет живой организм, находящийся в постоянном движении.Очевидно, что вся эта кипучая деятельность требует автоматизации. Для решения этой задачи существуют специальные программные средства, и в этой книге мы познакомим вам с самым популярным продуктом, предназначенным для автоматизации деятельности торгового предприятия – «1С Управление торговлей», которое реализовано на новейшей технологической платформе версии 1С 8.2.

Алексей Анатольевич Гладкий

Финансы / Программирование, программы, базы данных