C++. Сборник рецептов - [76]

Шрифт
Интервал

>  if (p != pDict_->end()) {          // Нашли, так что стираем

>   buf_.erase(i, buf_.length() - i); // и заменяем

>   buf_ += p->second;

>  }

> }

> buf_ += с;

>}


>int main() {

> // Создаем map

> StrStrMap dict;

> TextAutoField txt(&dict);

> dict["taht"] = "that";

> dict["right"] = "wrong";

> dict["bug"] = "feature";

> string tmp = "He's right, taht's a bug.";

> cout << "Оригинальная версия: " << tmp << '\n';

> for (string::iterator p = tmp.begin(); p != tmp.end(); ++p) {

>  txt.append(*p);

> }

> txt.getText(tmp);

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

>}

Вывод примера 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 StrStrMap;

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

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

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

>#include

>#include

>#include

>#include


>using namespace std;


>void split(const string& s, char c, vector& 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*>& data) {

> vector* p = NULL;

> string tmp;

> while (!in.eof()) {

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

>  p = new vector();

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

>                       // Рецепта 4.7

>  data.push_back(p);

>  cout << tmp << '\n';

>  tmp.clear();

> }

>}


>int main(int argc, char** argv) {

> if (argc < 2)

>  return(EXIT_FAILURE);

> ifstream in(argv[1]);

> if (!in)

>  return(EXIT_FAILURE);

> vector*> data;

> loadCSV(in, data);

> // Выполнить с данными какие-либо действия...

> for (vector*>::iterator p = data.begin();

>  p != data end(); ++p) {

>  delete *p; // Убедитесь, что p

> }           // разыменован!

>}

Обсуждение

В примере 4.32 почти нет ничего, что еще не было бы описано, >getline обсуждается в рецепте 4.19, a >vector — в рецепте 4.3. Единственный фрагмент, заслуживающий упоминания, — это выделение памяти.


Рекомендуем почитать
Изучаем Java EE 7

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)


Pro Git

Разработчику часто требуется много сторонних инструментов, чтобы создавать и поддерживать проект. Система Git — один из таких инструментов и используется для контроля промежуточных версий вашего приложения, позволяя вам исправлять ошибки, откатывать к старой версии, разрабатывать проект в команде и сливать его потом. В книге вы узнаете об основах работы с Git: установка, ключевые команды, gitHub и многое другое.В книге рассматриваются следующие темы:основы Git;ветвление в Git;Git на сервере;распределённый Git;GitHub;инструменты Git;настройка Git;Git и другие системы контроля версий.


Java 7

Рассмотрено все необходимое для разработки, компиляции, отладки и запуска приложений Java. Изложены практические приемы использования как традиционных, так и новейших конструкций объектно-ориентированного языка Java, графической библиотеки классов Swing, расширенной библиотеки Java 2D, работа со звуком, печать, способы русификации программ. Приведено полное описание нововведений Java SE 7: двоичная запись чисел, строковые варианты разветвлений, "ромбовидный оператор", NIO2, новые средства многопоточности и др.


Фундаментальные алгоритмы и структуры данных в Delphi

Книга "Фундаментальные алгоритмы и структуры данных в Delphi" представляет собой уникальное учебное и справочное пособие по наиболее распространенным алгоритмам манипулирования данными, которые зарекомендовали себя как надежные и проверенные многими поколениями программистов. По данным журнала "Delphi Informant" за 2002 год, эта книга была признана сообществом разработчиков прикладных приложений на Delphi как «самая лучшая книга по практическому применению всех версий Delphi».В книге подробно рассматриваются базовые понятия алгоритмов и основополагающие структуры данных, алгоритмы сортировки, поиска, хеширования, синтаксического разбора, сжатия данных, а также многие другие темы, тесно связанные с прикладным программированием.


Питон — модули, пакеты, классы, экземпляры

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.


Как пасти котов. Наставление для программистов, руководящих другими программистами

«Как пасти котов» – это книга о лидерстве и руководстве, о том, как первое совмещать со вторым. Это, если хотите, словарь трудных случаев управления IT-проектами. Программист подобен кошке, которая гуляет сама по себе. Так уж исторически сложилось. Именно поэтому так непросто быть руководителем команды разработчиков. Даже если вы еще месяц назад были блестящим и дисциплинированным программистом и вдруг оказались в роли менеджера, вряд ли вы знаете, с чего надо начать, какой выбрать стиль руководства, как нанимать и увольнять сотрудников, проводить совещания, добиваться своевременного выполнения задач.