Чтение онлайн

на главную - закладки

Жанры

C++. Сборник рецептов

Когсуэлл Джефф

Шрифт:

map
определяет
operator[]
, позволяющий получить значение данного ключа (на самом деле он возвращает ссылку на само значение), так что для его инкремента просто инкрементируется значение, индексируемое с помощью заданного ключа. Но здесь могут возникнуть небольшие осложнения. Что, если ключа в map еще нет? Разве мы не попытаемся увеличить несуществующий элемент, и не обрушится ли программа, как в случае с обычным массивом? Нет,
map
определяет
operator[]
не так, как другие контейнеры STL
или обычные массивы.

В

map operator[]
делает две вещи: если ключ еще не существует, он создает значение, используя конструктор типа значения по умолчанию, и добавляет в
map
эту новую пару ключ/значение, а если ключ уже существует, то никаких изменений не вносится. В обоих случаях возвращается ссылка на значение, определяемое ключом, даже если это значение было только что создано конструктором по умолчанию. Это удобная возможность (если вы знаете о ее существовании), так как он устраняет необходимость проверки в клиентском коде существования ключа перед его добавлением.

Теперь посмотрите на строки 32 и 33. Итератор указывает на члены, которые называются

first
и
second
— что это такое?
map
обманывает вас, используя для хранения пар имя/значение другой шаблон класса: шаблон класса
pair
, определенный в
<utility>
(уже включенный в
<map>
). При переборе элементов, хранящихся в
map
, вы получите ссылки на объекты
pair
. Работа с
pair
проста. Первый элемент пары хранится в элементе
first
, а второй хранится, естественно, в
second
.

В примере 4.27 я для чтения из входного потока непрерывных фрагментов текста использую

operator>>
, что отличается от некоторых других примеров. Я делаю это для демонстрации того, как это делается, но вам почти наверняка потребуется изменить его поведение в зависимости от определения «слова» текстового файла. Например, рассмотрим фрагмент вывода, генерируемого примером 4.27.

with присутствует 5 раз.

work присутствует 3 раз.

workers присутствует 3 раз.

workers, присутствует 1 раз.

years присутствует 2 раз.

years, присутствует 1 раз.

Обратите внимание, что точки в конце слов рассматриваются как части слов. Скорее всего, вам потребуется с помощью функций проверки символов из

<cctype>
и
<cwctype>
изменить определение слова так, чтобы оно означало только буквенно-цифровые символы, как это сделано в рецепте 4.17.

Смотри также

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

4.19. Добавление полей в текстовый файл

Проблема

Имеется текстовый файл, и в нем требуется сделать поля.

Другими словами, требуется сдвинуть обе стороны каждой строки, содержащей какие-либо символы, так, чтобы длина всех строк стала одинаковой.

Решение

Пример 4.28 показывает, как добавить в файл поля с помощью потоков,

string
и шаблона функции
getline
.

Пример 4.28. Добавление полей в текстовый файл

#include <iostream>

#include <fstream>

#include <string>

#include <cstdlib>

using namespace std;

const static char PAD_CHAR = '.';

// addMargins принимает два потока и два числа. Потоки используются для

// ввода и вывода. Первое из двух чисел представляет

// ширину левого поля (т.е. число пробелов, вставляемых в

// начале каждой строки файла). Второе число представляет

// общую ширину строки.

void addMargins(istream& in, ostream& out,

 int left, int right) {

 string tmp;

 while (!in.eof) {

getline(in, tmp, '\n'); // getline определена

// в <string>

tmp.insert(tmp.begin, left, PAD_CHAR);

rpad(tmp, right, PAD_CHAR); // rpad из рецепта

// 4.2

out << tmp << '\n';

 }

}

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

 int left = 8;

 int right = 72;

 if (argc == 5) {

left = atoi(argv[3]);

right = atoi(argv[4]);

 }

 addMargins(in, out, left, right);

 out.close;

 if (out)

return(EXIT_SUCCESS);

 else

return(EXIT_FAILURE);

Поделиться:
Популярные книги

Идеальный мир для Лекаря 11

Сапфир Олег
11. Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 11

Инкарнатор

Прокофьев Роман Юрьевич
1. Стеллар
Фантастика:
боевая фантастика
рпг
7.30
рейтинг книги
Инкарнатор

Миф об идеальном мужчине

Устинова Татьяна Витальевна
Детективы:
прочие детективы
9.23
рейтинг книги
Миф об идеальном мужчине

Все ведьмы – стервы, или Ректору больше (не) наливать

Цвик Катерина Александровна
1. Все ведьмы - стервы
Фантастика:
юмористическая фантастика
5.00
рейтинг книги
Все ведьмы – стервы, или Ректору больше (не) наливать

Вечный. Книга V

Рокотов Алексей
5. Вечный
Фантастика:
боевая фантастика
попаданцы
рпг
5.00
рейтинг книги
Вечный. Книга V

Надуй щеки!

Вишневский Сергей Викторович
1. Чеболь за партой
Фантастика:
попаданцы
дорама
5.00
рейтинг книги
Надуй щеки!

Командир штрафбата

Корчевский Юрий Григорьевич
3. Я из СМЕРШа
Фантастика:
боевая фантастика
попаданцы
альтернативная история
7.06
рейтинг книги
Командир штрафбата

Возвышение Меркурия. Книга 16

Кронос Александр
16. Меркурий
Фантастика:
попаданцы
аниме
5.00
рейтинг книги
Возвышение Меркурия. Книга 16

Проводник

Кораблев Родион
2. Другая сторона
Фантастика:
боевая фантастика
рпг
7.41
рейтинг книги
Проводник

Зайти и выйти

Суконкин Алексей
Проза:
военная проза
5.00
рейтинг книги
Зайти и выйти

Плеяда

Суконкин Алексей
Проза:
военная проза
русская классическая проза
5.00
рейтинг книги
Плеяда

Дело Чести

Щукин Иван
5. Жизни Архимага
Фантастика:
городское фэнтези
попаданцы
аниме
5.00
рейтинг книги
Дело Чести

Темный Лекарь 9

Токсик Саша
9. Темный Лекарь
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Темный Лекарь 9

Идеальный мир для Социопата 3

Сапфир Олег
3. Социопат
Фантастика:
боевая фантастика
6.17
рейтинг книги
Идеальный мир для Социопата 3