txt.append(*p);

 }

 txt.getText(tmp);

 cout << 'Исправленная версия. ' << tmp << ' ';

}

Вывод примера 3.2 таков.

Оригинальная версия: He's right, taht's a bug.

Исправленная версия: He's wrong, that's a feature.

Обсуждение

string и map удобны в ситуациях, когда требуется отслеживать ассоциации string. TextAutoField — это простой текстовый буфер, использующий string для хранения данных. Интересной TextAutoField делает ее метод append, который «слушает» пробелы или знаки пунктуации и при их появлении выполняет обработку.

Чтобы сделать автозамену работающей, требуется две вещи. Во-первых, требуется некий словарь, который содержит неправильно написанные варианты слов и связанные с ними правильные написания, map хранит пары ключ/значение, где ключ и значение могут быть любого типа, так что он является идеальным кандидатом на эту роль. В начале примера 4.31 имеется typedef для пар string:

typedef map<string, string> StrStrMap;

За более подробным описанием map обратитесь к рецепту 4.18. TextAutoField хранит указатель на map, так как, вероятнее всего, для всех полей потребуется только один общий словарь.

Предполагая, что клиентский код помещает в map что-то осмысленное, append просто должен периодически проверять trap. В примере 4.31 append ждет появления пробела или знака пунктуации. Для проверки на пробел можно использовать isspace, а для поиска знаков пунктуации можно использовать ispunct. Обе эти функции для узких символов определены в <cctype> (см. табл. 4.3).

Если вы не знакомы с использованием итераторов и методов поиска в контейнерах STL, то код, который выполняет проверку, требует некоторых пояснений, string tmp содержит последний фрагмент текста, который был добавлен в TextAutoField. Чтобы увидеть, был ли он написан с ошибками, поищите его в словаре вот так.

StrStrMap::iterator p = pDict->find(tmp);

if (p != pDict_->end()) {

Здесь важно то, что map::find в случае успеха поиска возвращает итератор, который указывает на пару, содержащую соответствующий ключ. Если поиск не дал результатов, то возвращается итератор, указывающий на область памяти после последнего элемента map, на который указывает map::end (именно так работают контейнеры STL, поддерживающие find). Если слово в map найдено, стираем из буфера старое слово и заменяем его правильной версией.

buf_.erase(i, buf_.length() - i);

buf_ += p->second;

Добавьте символ, который инициировал весь процесс (либо пробел, либо знак пунктуации), и все.

Смотри также

Рецепты 4.17, 4.18 и табл. 4.3.

4.23. Чтение текстового файла с разделителями-запятыми

Проблема

Требуется прочитать текстовый файл, чье содержимое разделено запятыми и новыми строками (или любой другой парой разделителей). Записи разделяются одним символом, а поля записи разделяются другим символом. Например, текстовый файл с разделителями-запятыми, содержащий информацию о сотрудниках, может выглядеть вот так.

Smith, Bill, 5/1/2002, Active

Stanford, John, 4/5/1999, Inactive

Такие файлы обычно временно хранят наборы данных, экспортируемые из электронных таблиц, баз данных или других форматов файлов.

Решение

Пример 4.32 демонстрирует, как это делается. Если читать текст в string непрерывными кусками с помощью getline (шаблон функции определен в <string>), то для анализа текста и создания структуры данных можно использовать функцию split, которая была представлена в рецепте 4.6.

Пример 4.32. Чтение файла с разделителями

#include <iostream>

#include <fstream>

#include <string>

#include <vector>

using namespace std;

void split(const string& s, char c, vector<string>& v) {

 int i = 0;

 int j = s.find(c);

 while (j >= 0) {

  v.push_back(s.substr(i, j-i));

  i = ++j;

  j = s.find(c, j);

  if (j < 0) {

   v.push_back(s.substr(i, s.length()));

  }

 }

}

void loadCSV(istream& in, vector<vector<string>*>& data) {

 vector<string>* p = NULL;

 string tmp;

 while (!in.eof()) {

  getline(in, tmp, ' '); // Получить следующую строку

  p = new vector<string>();

  split(tmp, '.', *p); // Использовать split из

                       // Рецепта 4.7

  data.push_back(p);

  cout << tmp << ' ';

  tmp.clear();

 }

}

Добавить отзыв
ВСЕ ОТЗЫВЫ О КНИГЕ В ИЗБРАННОЕ

0

Вы можете отметить интересные вам фрагменты текста, которые будут доступны по уникальной ссылке в адресной строке браузера.

Отметить Добавить цитату