Лабораторная работа ЛВП2019_2
Использование контейнеров STL map и vector
Цель работы
Целью работы является приобретение студентами навыков использования контейнеров map и vector из Стандартной Библиотеки Шаблонов (STL) С++.
Для достижения этой цели в ЛР предлагается разработать свой метод класса ReadDBTable для чтения таблиц БД из текстовых файлов. Разработка выполняется путем перегрузки дружественной для класса DBTableTxt функции
friend void ReadDBTable1(DBTableTxt& tab, string tabName),
которая читает таблицу tabName тестовой БД LibraryTxt из файла в объект типа DBTableTxt.
Задачи, решаемые при выполнении лабораторной работы:
- Создание приложения myDbms для работы с таблицами БД. Приложение использует статическую библиотеку классов для макета СУБД (библиотечные файлы dbmsLib_v1.lib и dbmsLib_v1.h предоставляются преподавателем).
- Подключение к проекту тестовой БД «Библиотека».
- Внесение изменений в данные таблиц БД с помощью методов класса DBTableTxt из статической библиотеки классов макета СУБД. Для хранения данных в DBTableTxt используется контейнер vector<Row>.
- Разработка собственной функции ReadDBTable1() для чтения таблиц БД из файла в объект типа DBTableTxt.
Планируемое время выполнения работы- 6 часов занятий в компьютерном зале (2 часа на создание проекта + 4 часа на разработку функции ReadDBTable1)+ 4 часа самостоятельной работы студента (СРС).
Порядок выполнения работы
2.1. Описание выполнения действий во всех лабораторных работах ЛВП приводится применительно к MS Visual Studio 2012.
!!! Обязательно сохраните копии таблиц тестовой БД.
2.2. Создайте консольное приложение myDbms и подключите к нему библиотеку dbmsLib_v1 (Как это делать, смотри ЛВП2019_ЛР1). Для выполнения операций с БД разработайте функцию int Menu().
2.3. Подключите к проекту тестовую БД. Для обращения к таблицам БД разработайте функцию, которая возвращает путь к файлам с таблицами относительно текущей папки проекта, используя в качестве параметров имя БД и имя таблицы. Функция использует соглашения по размещению БД, приведенные в ПКШ2019_ЛР1.
2.4. Используя интерфейс класса DBTableTxt, измените в БД группу студента и число экземпляров книги. Проверьте выполненные действия с помощью функции PrintTable.
2.5. Разработайте собственную функцию ReadDBTable1() для чтения таблиц БД из файла в объект типа DBTableTxt. Разработку выполняйте путем перегрузки дружественной функции
friend void ReadDBTable1(DBTableTxt& tab, string tabName).
Дружественные функции имеют доступ к закрытым членам классов.
Разработку делайте по шагам, контролируя выполнение каждого шага:
- Шаг 1. Чтение имени таблицы и имени ключевого столбца;
- Шаг 2. Чтение заголовка таблицы в поле Header columnHeaders, где Header – имя типа
map<string, ColumnDesc>;
При записи данных в map, контейнер можно рассматривать как массив, в котором в качестве индекса используется имя ключа (для map перегружена операция индексации).
Определения типов Header и ColumnDesc приведены в заголовочном файле библиотеки dbmstLib_v1.
- Шаг 3. Чтение данных таблицы в поле vector<Row> data, где Row – имя типа
map<string, void*>.
Для преобразования читаемых из текстового файла данных из типа string
в тип typeName, имя которого указано в заголовке столбца таблицы в CVS-файле,
используйте функцию из библиотеки dbmsLib_v1
void* GetValue(string value, string columnName, Header hdr);
Для проверки правильности выполненных действий вставьте в меню пункт для вызова функции ReadDBTable1() и выполняйте его для чтения таблицы вместо вызова ReadDBTableTxt().
- Шаг 4. Разработайте собственную функцию
void* GetValue1(string value, string columnName, Header hdr)
и вставьте её в ReadDBTable1() вместо функции GetValue().
После выполнения каждого шага выводите таблицу на экран.
После выполнения 1-го шага у вас должно распечататься имя таблицы и пустая таблица.
После выполнения 2-го шага в таблице должен появиться заголовок,
а после выполнения 3-его шага должна распечататься заполненная таблица.
Перед внесением изменений в разрабатываемую программу обязательно сохраняйте её текущую работающую версию. Чтобы не запутаться в версиях, сохраняйте их в папках с указанием даты создания и включайте номер версии в имя файла. Так как макет СУБД будет разрабатываться в течение всего семестра, это поможет вам избежать путаницы в именах файлов и связанных с ней потерь времени.
Ниже приведены фрагменты метода ReadDBTableTxt(), выполняющего чтение таблиц БД в объект типа DBTableTxt. Они должны помочь вам в выполнении задания.
Чтение заголовка в columnHeaders.
columnHeaders.clear();
char *token, *next_token;
fin.getline(line, 200); //чтение заголовка
next_token=line;
//цикл по словам (лексемам) в строке
ColumnDesc colHdr;
while((token = strtok_s(next_token, delims, &next_token))!= NULL)
{
strcpy_s(colHdr.colName,token);
token = strtok_s(next_token, delims, &next_token);
colHdr.colType=GetType(token);
token = strtok_s(next_token, delims, &next_token);
colHdr.length=atoi(token);
strArray.push_back(colHdr);
}
Header hdr;
for (unsigned int j = 0; j < strArray.size(); j ++)
{
hdr[strArray[j].colName]=strArray[j];
}
SetHeader(hdr);
Чтение строк данных.
//читаем строки в line (до EOF) и записываем их в table.data
data.clear();
while (fin.getline(line, 200))
{
Row row=*(new Row());//буфер для формирования строки таблицы
int j = 0;
token = strtok_s(line, delims, &next_token);
//цикл по столбцам (словам) в строке
while(token)
{
string value=token;
//добавление поля в строку с преобразованием типа
//strArray[j] - имя столбца в заголовке таблицы
row[strArray[j].colName]=GetValue(value,strArray[j].colName,columnHeaders); j=j++;//индекс следуещего столбца в векторе strArray
token = strtok_s(next_token, delims, &next_token);
}
data.push_back(row);//добавить строку данных в таблицу
3. Контрольные вопросы и задания
3.1. Что такое контейнер?
3.2. Для чего и как используются шаблоны?
3.3. Что такое последовательный контейнер?
3.4. Что такое ассоциативный контейнер?
3.5. Что хранится в узлах контейнера map?
3.6. Что такое итератор?
3.7. Как получить доступ к данным в контейнере vector?
3.8. Как получить доступ к данным в контейнере map?