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

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

Жанры

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

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

Шрифт:

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, '\n'); // Получить следующую строку

p = new vector<string>;

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<vector<string>*> data;

 loadCSV(in, data);

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

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

p != data end; ++p) {

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

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

}

Обсуждение

В примере 4.32 почти нет ничего, что еще не было бы описано,

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

loadCSV
создает новый
vector
для каждой прочитанной строки данных и сохраняет его в другом vector, состоящем из указателей на
vector
. Так как память для каждого из этих векторов выделяется из кучи, кто-то должен удалить ее, и этот кто-то — это вы (а не реализация
vector
).

vector
ничего не знает о том, содержит ли он значение или указатель на значение или что-либо еще. Все, что он знает, — это то, что при его удалении он должен вызвать деструктор для каждого содержащегося в нем элемента. Если
vector
хранит объекты, то все нормально, объект будет удален правильно. Но если
vector
содержит указатели, то удалены будут указатели, а не объекты, на которые они указывают.

Есть два способа гарантировать освобождение памяти. Первый заключается в том, что сделано в примере 4.32 вручную, как здесь.

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

 p != data.end; ++p) {

 delete *p;

}

Либо можно использовать указатель со счетчиком ссылок, такой как

smart_ptr
из проекта Boost, который станет частью будущего стандарта C++0x. Но реализация этого нетривиальна, так что я рекомендую почитать, что такое
smart_ptr
и как он работает. Для получения дополнительной информации по Boost посетите его домашнюю страницу по адресу www.boost.org.

4.24. Использование регулярных выражений для разделения строки

Проблема

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

Решение

Используйте шаблон класса

regex
Boost.
regex
позволяет использовать для строк и текстовых данных регулярные выражения. Пример 4.33 показывает, как использовать
regex
для разделения строк.

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

Барон играет по своим правилам

Ренгач Евгений
5. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
фантастика: прочее
5.00
рейтинг книги
Барон играет по своим правилам

Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Клеванский Кирилл Сергеевич
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.51
рейтинг книги
Сердце Дракона. нейросеть в мире боевых искусств (главы 1-650)

Герцогиня в ссылке

Нова Юлия
2. Магия стихий
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Герцогиня в ссылке

Ну привет, заучка...

Зайцева Мария
Любовные романы:
эро литература
короткие любовные романы
8.30
рейтинг книги
Ну привет, заучка...

На Ларэде

Кронос Александр
3. Лэрн
Фантастика:
фэнтези
героическая фантастика
стимпанк
5.00
рейтинг книги
На Ларэде

Сердце Дракона. Том 12

Клеванский Кирилл Сергеевич
12. Сердце дракона
Фантастика:
фэнтези
героическая фантастика
боевая фантастика
7.29
рейтинг книги
Сердце Дракона. Том 12

Истинная поневоле, или Сирота в Академии Драконов

Найт Алекс
3. Академия Драконов, или Девушки с секретом
Любовные романы:
любовно-фантастические романы
6.37
рейтинг книги
Истинная поневоле, или Сирота в Академии Драконов

Кодекс Охотника. Книга VI

Винокуров Юрий
6. Кодекс Охотника
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Кодекс Охотника. Книга VI

Гардемарин Ее Величества. Инкарнация

Уленгов Юрий
1. Гардемарин ее величества
Фантастика:
городское фэнтези
попаданцы
альтернативная история
аниме
фантастика: прочее
5.00
рейтинг книги
Гардемарин Ее Величества. Инкарнация

Сама себе хозяйка

Красовская Марианна
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Сама себе хозяйка

Душелов. Том 3

Faded Emory
3. Внутренние демоны
Фантастика:
альтернативная история
аниме
фэнтези
ранобэ
хентай
5.00
рейтинг книги
Душелов. Том 3

Газлайтер. Том 10

Володин Григорий
10. История Телепата
Фантастика:
боевая фантастика
5.00
рейтинг книги
Газлайтер. Том 10

Стеллар. Заклинатель

Прокофьев Роман Юрьевич
3. Стеллар
Фантастика:
боевая фантастика
8.40
рейтинг книги
Стеллар. Заклинатель

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

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