Решение

Для чтения непрерывной последовательности непробельных символов из потока в строку используйте шаблон функции operator>>, определенный в <string>. Затем используйте его двойника operator<<, который записывает каждую из этих последовательностей в выходной поток, и после каждой из них добавьте по одному пробелу. Пример 4.30 дает краткий пример этой методики.

Пример 4 30. Замена последовательностей пробелов на один пробел

#include <iostream>

#include <fstream>

#include <string>

using namespace std;

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

 if (argc < 3)

  return(EXIT_FAILURE);

 ifstream in(argv[1]);

 ofstream out(argv[2]);

 if (!in || !out)

  return(EXIT_FAILURE);

 string tmp;

 in >> tmp;  // Прочитать первое слове

 out << tmp; // Записать его в выходной поток

 while (in >> tmp) { // operator>> игнорирует пробелы, так что все, что

  out << ' ';        // я должен сделать, - это записать пробел и каждую

  out << tmp;        // последовательность «непробелов»

 }

 out.close();

}

Обсуждение

Это просто сделать, если использовать потоки и строки. Даже если требуется реализовать другой вариант этого — например, чтобы сохранить переходы на новую строку, — эта методика будет работать. Если требуется добавить переходы на новые строки, для их расстановки в нужных местах используйте решение, представленное в рецепте 4.16.

Смотри также

Рецепты 4.15 и 4.16.

4.22. Автозамена текста при изменении буфера

Проблема

Имеется класс, который представляет некий тип текстового поля или документа, и по мере добавления в него текста требуется автоматически корректировать неправильно написанные слова, как это делает функция Autocorrect (Автозамена) в Microsoft Word.

Решение

Это можно реализовать в относительно небольшом коде, если использовать map, который определен в <map>, string и различные возможности стандартной библиотеки. Пример 4.31 показывает, как это делается.

Пример 4.31. Автозамена текста

#include <iostream>

#include <string>

#include <cctype>

#include <map>

using namespace std;

typedef map<string, string> StrStrMap;

// Класс для хранения текстовых полей

class TextAutoField {

public:

 TextAutoField(StrStrMap* const p) : pDict_(p) {}

 ~TextAutoField() {}

 void append(char c);

 void getText(string& s) {s = buf_;}

private:

 TextAutoField();

 string buf_;

 StrStrMap* const pDict ;

};

// Добавление с автозаменой

void TextAutoField::append(char c) {

 if ((isspace(c) || ispunct(c)) &&     // Выполнять автоза-

  buf_.length() > 0 &&                 // мену, только когда вводятся

  !isspace(buf_[buf_.length() - 1])) { // ws или punct

  string::size_type i = buf_.find_last_of(' f v');

  i = (i == string::npos) ? 0 : ++i;

  string tmp = buf_.substr(i, buf_.length() - i);

  StrStrMap::const_iterator p = DDict_->find(tmp);

  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 << ' ';

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

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

0

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

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