Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C++ Builder > Парсинг файла


Автор: gather 27.5.2008, 18:18
Доброе время суток всем ;)

В наличии имеется файл со следующей структурой:
Код

[POLYLINE]
Type=0x6
Label=Каменный Лог
StreetDesc=Каменный Лог
CityIdx=1
RoadID=21
RouteParam=3,0,0,0,0,0,0,0,0,0,0,0
Data0=(52.61033,39.59260),(52.61024,39.59249),(52.61020,39.59239),(52.61017,39.59219)
Nod1=0,1487,0
Nod2=3,1519,0
[END]

[POLYLINE]
Type=0x6
CityIdx=1
RoadID=22
RouteParam=3,0,0,0,0,0,0,0,0,0,0,0
Data0=(52.61009,39.59466),(52.60953,39.59616)
Nod1=0,1502,0
Nod2=1,1496,0
[END]

Записей может быть ооочень много. (средний размер текстового файла 15Мб)

Посоветуйте пожалуйста, как лучше обрабатывать данный файл, учитывая то, что мне необходимо отрисовывать на объекте с помощью polyline и polygon объекты, по координатам, указанным в Data0 свойстве.

 smile 

Автор: Rififi 27.5.2008, 18:41
Цитата(gather @  27.5.2008,  18:18 Найти цитируемый пост)
Посоветуйте пожалуйста, как лучше обрабатывать данный файл

построчное чтение и накопление данных между [Метка] .. [END]
для анализа отдельных строк можно воспользоваться регулярными выражениями

Автор: gather 27.5.2008, 18:57
Rififi, я понимаю что построчное чтение.
Каким лучше способом обрабатывать и где и как хранить обработанные данные, ибо отрисовывать надо не 1 раз. А по мере изменения координат. А читать снова весь файл - ИМХО непрактично.

Я склоняюсь в сторону TStringList, но как он поведет себя на таких объемах, не будет ли тормозить вот в чем вопрос.

Автор: jonie 27.5.2008, 19:39
а чем обычные контейнеры, типа std::vector (при опред условиях, наверно, лучши выбор) хуже?

Автор: Rififi 27.5.2008, 19:50
gather, 
я понимаю что построчное чтение.
тогда задавай конкретный вопросы.

то, что описывается в секции POLYLINE представляется как единая структура данных.
соответственно по мере парсинга накапливаешь массив таких структур.

как хранить обработанные данные
Type => enum
Label => std::[w]string
StreetDesc => std::[w]string
CityIdx => [u]int
RoadID => [u]int
RouteParam => int* или std::vector<int>
Data0 => массив или std::vector of Point { x, y }
Nod1 => int* или std::vector<int>
Nod2 => int* или std::vector<int>

Автор: gather 27.5.2008, 20:30
Rififi, извиняюсь за некорректную постановку вопроса.

В итоге. Имеем из секции Data0 std::vector of Point { x, y }

Можно пример, как использовать данный вектор? Просто никогда с ними не работал.  smile 

По остальному - огромное спасибо.

Автор: Lazin 27.5.2008, 20:54
Цитата(gather @  27.5.2008,  18:57 Найти цитируемый пост)
Я склоняюсь в сторону TStringList, но как он поведет себя на таких объемах, не будет ли тормозить вот в чем вопрос.

плохо он себя поведет smile 

здесь есть 2 варианта, либо мы загружаем все в память, либо нет. В первом случае потребуется описать POLYLINE как класс, читать секции [POLYLINE]...[END], парсить и создовать объекты класса Polyline, а потом класть их в тот-же вектор...
Во втором случае можно парсить некоторое количество секций, отрисовывать их, опять парсить и тд... будет то-же самое, но памяти потребуется меньше..

Добавлено через 1 минуту и 1 секунду
Цитата(gather @  27.5.2008,  20:30 Найти цитируемый пост)
Можно пример, как использовать данный вектор? Просто никогда с ними не работал.

на форуме их вагон и маленькая тележка

Автор: artsb 27.5.2008, 20:57
Цитата(gather @  27.5.2008,  20:30 Найти цитируемый пост)
Можно пример, как использовать данный вектор?

Код

#include <vector.h>
//...
vector<int> MyVector;
// добавлять так, например в конец:
int a=10;
MyVector.push_back(a);
// удалять так:
vector<int>::iterator iter=MyVector.begin()+Index; // здесь Index - это смещение относительно начала вектора (переменная типа int)
MyVector.erase(iter);
// очистить так:
MyVector.clear();

Автор: Rififi 27.5.2008, 21:03
Можно пример, как использовать данный вектор? Просто никогда с ними не работал. 
Код
struct Point { float x, y; };
std::vector<Point> v;

// создаём и инициализируем экземпляр структуры Point
Point pt;
pt.x = ...
pt.y = ...

v.push_back(pt); // копируем pt к себе (терерь размер = 1)
Point first = v[0]; // достаём из вектора копию первого элемента


Автор: gather 27.5.2008, 21:26
Rififi, artsb, Lazin,  Спасибо.


Rififi, Если я правильно понимаю, то в приведенном Вами примере - в вектор будут складываться значения x,y одной секции [POLYLINE][END]

Как быть, если таких секций около 15000?

Автор: Lazin 27.5.2008, 22:04
Цитата(gather @  27.5.2008,  21:26 Найти цитируемый пост)
Как быть, если таких секций около 15000? 

Код


class Polyline
{
std::vector<Point> vertices;
...
public:
...
};

std::vector<Polyline> sections;


как то так

Автор: Rififi 27.5.2008, 22:21
то есть код парсинга может выглядеть примерно так

Код
Reader rd("data.txt"); // Сферический реадер из файла
while (!rd.eof()) // крутим цикл пока не конец файла
{
    Polyline pl;
    if (rd.Parse(pl)) // если парсинг очередной секции произведён успешно...
        sections.push_back(pl);
}
// дальше юзаем заполненный вектор класов
(void) sections;

Автор: gather 27.5.2008, 22:40
Ясно, спасибо.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)