Долмашняя фонотека
Введение
Цель выполнения курсового проекта состоит в том, чтобы научится описывать предметную область реального мира – объект и его атрибуты, закрепить навыки использования основных структур данных, способов их описания и основных операций над ними. Освоить разработку удобного пользовательского интерфейса.
Тема моего курсового проекта – домашняя фонотека.
- Содержательная постановка и описание задачи
Домашняя фонотека – это база данных, содержащая сведения о домашней музыкальной коллекции.
Программа должна обладать следующими функциями:
- Считывать исходные данные из текстового файла, который создается самостоятельно.
- Возможность осуществления сортировки данных по любому выбранному полю.
- Возможность осуществления поиска данных по любому выбранному полю.
- Возможность отображения результатов на экране.
- Формирование выходного файла.
При этом в конечном программном продукте должен быть интуитивно понятный и доступный любым пользователям интерфейс.
- Атрибуты объекта и представлен
ие данных в программе
Так как, предметная область – домашняя фонотека, то объектом является музыкальная композиция.
Выбираем следующие атрибуты музыкальной композиции:
- Жанр;
- Исполнитель;
- Название;
- Альбом;
- Год выхода.
Выполняем преобразование атрибутов в поля пользовательских типов, таблица 1.
Таблица 1
Музыкальная композиция |
Song |
Тип данных | |
Жанр |
Genre |
CString |
Класс строк |
Исполнитель |
Artist |
CString |
Класс строк |
Название |
Name |
CString |
Класс строк |
Альбом |
Album |
CString |
Класс строк |
Год выхода |
Year |
Int |
Целое |
- Описание программы создания набора данных
Класс представляет собой
отдельную концепцию
Определение класса можно проиллюстрировать следующим образом (рис. 1).
Рис. 1. Уровни видимости класса
Атрибуты, описывающие музыкальную композицию, будут храниться в классе Song. Это простой класс с конструктором, который инициализирует все поля и методы доступа к данным.
Для определения класса
предусмотрено специальное
Ниже приведена часть программы, описывающая класс Song.
class Song
{
public:
// Конструктор
Song(CString s);
// Жанр
CString GetGenre() { return m_genre; }
// Исполнитель
CString GetArtist() { return m_artist; }
// Название
CString GetName() { return m_name; }
// Альбом
CString GetAlbum() { return m_album; }
// Год
int GetYear() { return m_year; }
// Вывести описание песни в поток
void OutToStream(fstream& f);
// Сравнить два описания песни
int Compare(Song* s, int byField);
// Сравнить со строкой
int Compare(CString s, int byField);
private:
CString m_genre; // Жанр
CString m_artist; // Исполнитель
CString m_name; // Название
CString m_album; // Альбом
int m_year; // Год
};
Входные данные программы представляют собой текстовый файл с названием songs.txt. Файл должен располагаться рядом с исполняемым файлом.
Каждая строка текстового файла описывает одну музыкальную композицию домашней фонотеки. В строке располагаются атрибуты, описывающие музыкальную композицию. Атрибуты разделены точкой с запятой.
В строке расположены следующие атрибуты:
- Жанр музыкальной композиции.
- Исполнитель.
- Название музыкальной композиции.
- Альбом.
- Год выхода.
Пример файла приведен ниже:
Рок;Машина времени;Поворот;Лучшее;1995
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля В.;Скрипка Пагпнини;Дни летят;1987
Классика;Вивальди;Зима;Лучшее;
- Описание программы формирования выходного документа
К выходным документам относятся:
- Вывод информации на экран;
- Вывод информации в файл.
Пример формирования выходного документа на экран см. в приложении 4 рис. 4. 1.
Экран в данной программе состоит из двух частей:
- Нижняя. Содержит пять столбцов, в которых расположены данные о музыкальных композициях.
- Верхняя. В ней находятся поля выбора данных для сортировки и поиска, а также кнопки «Сортировать» и «Поиск», осуществляющие соответствующие действия.
Найденные по запросу данные выделяются на экране серым цветом.
Выходными данными программы в файл является текстовый файл result.txt. В файл записываются результаты загрузки данных, результаты сортировки и результаты поиска.
Пример выходного файла приведен ниже:
ЗАГРУЗКА файла "songs.txt"
Рок;Машина времени;Поворот;Лучшее;1995
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля В.;Скрипка Пагпнини;Дни летят;1987
Классика;Вивальди;Зима;Лучшее;
СОРТИРОВКА по полю: "Исполнитель"
Классика;Вивальди;Зима;Лучшее;
Рок;Машина времени;Поворот;Лучшее;1995
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля В.;Скрипка Пагпнини;Дни летят;1987
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
СОРТИРОВКА по полю: "Название"
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Классика;Вивальди;Зима;Лучшее;
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
Эстрада;Мигуля
В.;Скрипка Пагпнини;Дни летят;
СОРТИРОВКА по полю: "Альбом"
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля
В.;Скрипка Пагпнини;Дни летят;
Классика;Вивальди;Зима;Лучшее;
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
СОРТИРОВКА по полю: "Год"
Классика;Вивальди;Зима;Лучшее;
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля
В.;Скрипка Пагпнини;Дни летят;
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
ПОИСК значения "Эстрада" в поле "Жанр"
Классика;Вивальди;Зима;Лучшее;
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля
В.;Скрипка Пагпнини;Дни летят;
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
НАЙДЕНО:
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
ПОИСК значения "Пугачева А." в поле "Исполнитель"
Классика;Вивальди;Зима;Лучшее;
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля
В.;Скрипка Пагпнини;Дни летят;
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
НАЙДЕНО:
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
ПОИСК значения "Зима" в поле "Название"
Классика;Вивальди;Зима;Лучшее;
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля В.;Скрипка Пагпнини;Дни летят;1987
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
НАЙДЕНО:
Классика;Вивальди;Зима;Лучшее;
ПОИСК значения "Дни летят" в поле "Альбом"
Классика;Вивальди;Зима;Лучшее;
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля
В.;Скрипка Пагпнини;Дни летят;
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
НАЙДЕНО:
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
ПОИСК значения "1995" в поле "Год"
Классика;Вивальди;Зима;Лучшее;
Эстрада;Мигуля В.;Домик на окраине;Дни летят;1987
Эстрада;Мигуля
В.;Скрипка Пагпнини;Дни летят;
Попса;Пугачева А.;Миллион алых роз;Лучшее;1989
Рок;Машина времени;Поворот;Лучшее;1995
НАЙДЕНО:
Рок;Машина времени;Поворот;Лучшее;1995
- Описание программы формировани
я списковой структуры
Динамические структуры по определению характеризуются отсутствием физической смежности элементов структуры в памяти непостоянством и непредсказуемостью размера (числа элементов) структуры в процессе ее обработки. Поскольку элементы динамической структуры располагаются по непредсказуемым адресам памяти, адрес элемента такой структуры не может быть вычислен из адреса начального или предыдущего элемента. Для установления связи между элементами динамической структуры используются указатели, через которые устанавливаются явные связи между элементами. Такое представление данных в памяти называется связным.
Элемент динамической структуры состоит из двух полей:
- информационного поля или поля данных, в котором содержатся те данные, ради которых и создается структура; в общем случае информационное поле само является интегрированной структурой - вектором, массивом, записью и т.п.;
- поле связок, в котором содержатся один или несколько указателей, связывающий данный элемент с другими элементами структуры;
Когда связное представление данных используется для решения прикладной задачи, для конечного пользователя "видимым" делается только содержимое информационного поля, а поле связок используется только программистом-разработчиком.
Достоинства связного представления данных - в возможности обеспечения значительной изменчивости структур;
- размер структуры ограничивается только доступным объемом машинной памяти;
- при изменении логической последовательности элементов структуры требуется не перемещение данных в памяти, а только коррекция указателей. [9]
Узел списка
Узел списка представлен классом RingListNode. Класс имеет три поля:
- Указатель на класс Song.
- Указатель на предыдущий узел.
- Указатель на следующий узел.
Ниже приведен текст
программы, описывающий класс RingListNode
class RingListNode
{
public:
// Конструктор
RingListNode(Song* s);
// Деструктор
~RingListNode();
// Данные
Song* GetData() { return m_data; }
// Предыдущий узел
RingListNode* GetPrev() { return m_prev; }
// Изменить предыдущий узел
void SetPrev(RingListNode* node) { m_prev = node; }
// Следующий узел
RingListNode* GetNext() { return m_next; }
// Изменить следующий узел
void SetNext(RingListNode* node) { m_next = node; }
private:
Song* m_data; // Данные
RingListNode* m_next; // Предыдущий узел
RingListNode* m_prev; // Следующий узел
};
Кольцевой список
Кольцевой список – это частный случай связанного списка, у которого самый первый и самый последний элементы ссылаются друг на друга. [8]
Кольцевой список реализован в виде класса RingList.
class RingList
{
public:
// Конструктор
RingList();
// Деструктор
~RingList();
// Добавить в список
void Insert(Song* s);
// Проверить что пустой
BOOL Empty() { return m_head == NULL; }
// Установить указатель на первый узел
void Reset() { m_current = m_head; }
// Перевести указатель на следующий узел
BOOL Next();
// Данные текущего узла
Song* Current() { return m_current->GetData(); }
// Сортировка простым включением
void InclusionSort(int byField);
// Последовательный поиск
Song* Search(CString s, int byField);
// Вывести список в поток
void OutToStream(fstream& f);
private:
RingListNode* m_head; // Начальный узел
RingListNode* m_current; // Текущий узел
// Поменять два узла местами
void Swap(RingListNode* n1, RingListNode* n2);
};
- Технология обработки данных
Сразу после запуска программа загружает данные из файла songs.txt в кольцевой список, отображает загруженные данные на экране и выводит результат загрузки в файл result.txt. Далее программа ждет ввода пользователя.
Если пользователь выбрал сортировку, то программа выполняет сортировку списка простым включением и выводит результат сортировки.
Если пользователь выбрал поиск, то
программа выполняет
Блок схема алгоритма программы приведена в Приложении 5.
Сортировка
В программе реализован алгоритм сортировки простым включением. Каждый элемент списка, начиная со второго, последовательно сравнивается с предыдущими элементами. Если предыдущий элемент больше, то элементы меняются местами. Рисунок 2 демонстрирует работу алгоритма сортировки. [4]
Программная реализация приведена ниже:
Сортировка простым включением
void RingList::InclusionSort(int byField)
{
if (Empty())
return;
Reset();
while (Next())
{
RingListNode* n2 = m_current;
RingListNode* n1 = n2->GetPrev();
while (n2 != m_head && n2->GetData()->Compare(n1->
{
Swap(n1, n2);
n1 = n2->GetPrev();
}
}
}
Блок-схема алгоритма приведена в Приложении 5.
Рис. 2. Графическое представление алгоритма сортировки
Поиск
В программе реализован последовательный поиск. Последовательно, начиная с самого первого элемента списка, сравниваем элементы с искомым значением, пока не будет найден нужный элемент. [3]
// Последовательный поиск
Song* RingList::Search(CString s, int byField)
{
if (Empty())
return NULL;
Reset();
do
{
if (Current()->Compare(s, byField) == 0)
return Current();
}
while (Next());
return NULL;
}
Блок-схема алгоритма приведена в Приложении 5.
Заключение
В процессе выполнения курсового проекта я научился описывать конкретную предметную область, обрабатывать динамические структуры данных средствами алгоритмического языка Си++.
Выполняя полученное задание, получил блок-схемы алгоритмов сортировки и поиска данных.
Преимущество блок-схем состоит в их наглядности.
Полученная мной программа осуществляет чтение данных из текстового файла, сортировку и поиск данных по любому полю, создает выходной файл.
Список литературы
- Н. Б. Культин, С/С++ в задачах и примерах, СПб: БХВ-Петербург, 2001.
- Т. А. Павловская, С/С++. Программирование на языке высокого уровня, СПб: Питер, 2005.
- А. А. Кубенский, Структуры и алгоритмы обработки данных, СПб: БХВ-Петербург, 2004.
- Л. Г. Гагарина, В. Д. Колдаев, Алгоритмы и структуры данных, М.: Финансы и статистика; ИНФРА-М, 2009.
- В. Д. Колдаев, Основы алгоритмизации и программирования, М.: ИД «ФОРУМ» - ИНФРА-М, 2006.
- Г. Шилдт, Искусство программирования на С++, БХВ-Петербург, 2005.
- В. В. Подбельский, Язык Си++, Финанся и статистика, 2009.
- Р. Лафоре, Объектно-ориентированное программирование, Питер, 2003.
- В. Кораблев, Visual C++.NET, Питер, 2010.
- Х. М. Дейтел, П. Дж. Дейтел, Как программировать на C++, Бином, 2001.
Приложение 1
Графическое описание данных
Приложение 2
Представление данных в памяти ЭВМ
Song | ||
Genre |
CString |
2 байта |
Artist |
CString |
2 байта |
Name |
CString |
2 байта |
Album |
CString |
2 байта |
Year |
Int |
2 байта |
|
|
Приложение 3
Схема списковой структуры
Рис. 3. 1. Кольцевой список
Приложение 4
Формат выходного документа
Рис. 4. 1. Поиск данных
Рис. 4. 2. Сортировка данных
Рис. 4. 3. Текстовый файл
Приложение 5
Схема последовательности обработки данных
Рис. 5.1. Блок-схема основной программы
Рис. 5. 2. Блок-схема алгоритма сортировки
Рис. 5. 3. Блок-схема алгоритма поиска
Приложение 6
Листинг программы
Music.h
#pragma once
#include "resource.h" // main symbols
class CMusicApp : public CWinApp
{
public:
CMusicApp();
// Overrides
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMusicApp)
public:
virtual BOOL InitInstance();
//}}AFX_VIRTUAL
// Implementation
//{{AFX_MSG(CMusicApp)
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
};
Music.cpp
#include "stdafx.h"
#include "Music.h"
#include "MusicDlg.h"
BEGIN_MESSAGE_MAP(CMusicApp, CWinApp)
//{{AFX_MSG_MAP(CMusicApp)
//}}AFX_MSG
ON_COMMAND(ID_HELP, CWinApp::OnHelp)
END_MESSAGE_MAP()
CMusicApp::CMusicApp()
{
}
CMusicApp theApp;
BOOL CMusicApp::InitInstance()
{
// Standard initialization
#ifdef _AFXDLL
Enable3dControls(); // Call this when using MFC in a shared DLL
#else
Enable3dControlsStatic(); // Call this when linking to MFC statically
#endif
CMusicDlg dlg;
m_pMainWnd = &dlg;
int nResponse = dlg.DoModal();
if (nResponse == IDOK)
{
}
else if (nResponse == IDCANCEL)
{
}
// Since the dialog has been closed, return FALSE so that we exit the
// application, rather than start the application's message pump.
return FALSE;
}
MusicDlg.h
#pragma once
#include "RingList.h"
class CMusicDlg : public CDialog
{
// Construction
public:
CMusicDlg(CWnd* pParent = NULL); // standard constructor
// Dialog Data
//{{AFX_DATA(CMusicDlg)
enum { IDD = IDD_MUSIC_DIALOG };
CListCtrl m_list1;
CComboBox m_combo2;
CComboBox m_combo1;
CString m_edit1;
//}}AFX_DATA
// ClassWizard generated virtual function overrides
//{{AFX_VIRTUAL(CMusicDlg)
protected:
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
//}}AFX_VIRTUAL
// Implementation
protected:
HICON m_hIcon;
// Generated message map functions
//{{AFX_MSG(CMusicDlg)
virtual BOOL OnInitDialog();
afx_msg void OnButton1();
afx_msg void OnButton2();
//}}AFX_MSG
DECLARE_MESSAGE_MAP()
private:
RingList m_songs;
// Заполнить таблицу из списка
void FillTable();
// Выделить строку таблицы
void SelectRow(Song* s);
};
MusicDlg.cpp
#include "stdafx.h"
#include "Music.h"
#include "MusicDlg.h"
CString columnNames[] = {"Жанр", "Исполнитель", "Название", "Альбом", "Год"};
CMusicDlg::CMusicDlg(CWnd* pParent /*=NULL*/)
: CDialog(CMusicDlg::IDD, pParent)
{
//{{AFX_DATA_INIT(CMusicDlg)
m_edit1 = _T("");
//}}AFX_DATA_INIT
m_hIcon = AfxGetApp()->LoadIcon(IDR_
}
void CMusicDlg::DoDataExchange(
{
CDialog::DoDataExchange(pDX);
//{{AFX_DATA_MAP(CMusicDlg)
DDX_Control(pDX, IDC_LIST1, m_list1);
DDX_Control(pDX, IDC_COMBO2, m_combo2);
DDX_Control(pDX, IDC_COMBO1, m_combo1);
DDX_Text(pDX, IDC_EDIT1, m_edit1);
//}}AFX_DATA_MAP
}
BEGIN_MESSAGE_MAP(CMusicDlg, CDialog)
//{{AFX_MSG_MAP(CMusicDlg)
ON_BN_CLICKED(IDC_BUTTON1, OnButton1)
ON_BN_CLICKED(IDC_BUTTON2, OnButton2)
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
BOOL CMusicDlg::OnInitDialog()
{
CDialog::OnInitDialog();
SetIcon(m_hIcon, TRUE); // Set big icon
SetIcon(m_hIcon, FALSE); // Set small icon
// Стиль таблицы
m_list1.SetExtendedStyle(m_
// Добавляем столбцы в таблицу
m_list1.InsertColumn(0, columnNames[0], LVCFMT_LEFT, 100);
m_list1.InsertColumn(1, columnNames[1], LVCFMT_LEFT, 100);
m_list1.InsertColumn(2, columnNames[2], LVCFMT_LEFT, 100);
m_list1.InsertColumn(3, columnNames[3], LVCFMT_LEFT, 100);
m_list1.InsertColumn(4, columnNames[4], LVCFMT_LEFT, 100);
// Названия столбцов для сортировки
m_combo1.AddString(
m_combo1.AddString(
m_combo1.AddString(
m_combo1.AddString(
m_combo1.AddString(
m_combo1.SetCurSel(0);
// Названия столбцов для поиска
m_combo2.AddString(
m_combo2.AddString(
m_combo2.AddString(
m_combo2.AddString(
m_combo2.AddString(
m_combo2.SetCurSel(0);
// Загружаем описание режущего инструмента из файла cutters.txt
try
{
fstream f("songs.txt", ios::in);
while (!f.eof())
{
CString s;
f.getline(s.GetBuffer(1000), 1000);
s.ReleaseBuffer();
if (s.GetLength() > 0)
{
Song* n = new Song(s);
m_songs.Insert(n);
}
}
f.close();
}
catch (std::exception& e)
{
MessageBox(e.what(), "Ошибка", MB_OK|MB_ICONERROR);
}
// Показываем список
FillTable();
// Результат загрузки
try
{
fstream f("result.txt", ios::out | ios::trunc);
f << "ЗАГРУЗКА файла \"songs.txt\"" << endl;
m_songs.OutToStream(f);
}
catch (std::exception& e)
{
MessageBox(e.what(), "Ошибка", MB_OK|MB_ICONERROR);
}
return TRUE; // return TRUE unless you set the focus to a control
}
void CMusicDlg::OnButton1()
{
// Индекс поля для сортировки
int byField = m_combo1.GetCurSel();
// Сортируем
m_songs.InclusionSort(byField)
// Показываем
FillTable();
// результат сортировки
try
{
fstream f("result.txt", ios::out | ios::app);
f << endl << "СОРТИРОВКА по полю: \"" << columnNames[byField] << "\"" << endl;
m_songs.OutToStream(f);
}
catch (std::exception& e)
{
MessageBox(e.what(), "Ошибка", MB_OK|MB_ICONERROR);
}
}
void CMusicDlg::OnButton2()
{
// Считываем значения из элементов управления
UpdateData(TRUE);
// индекс поля для поиска
int byField = m_combo2.GetCurSel();
// ищем
Song *s = m_songs.Search(m_edit1, byField);
// Выделяем
SelectRow(s);
// результат поиска
try
{
fstream f("result.txt", ios::out | ios::app);
f << endl << "ПОИСК значения \"" << m_edit1 << "\" в поле \"" << columnNames[byField] << "\"" << endl;
m_songs.OutToStream(f);
if (s)
{
f << "НАЙДЕНО: " << endl;
s->OutToStream(f);
}
else
{
f << "НЕ НАЙДЕНО" << endl;
}
}
catch (std::exception& e)
{
MessageBox(e.what(), "Ошибка", MB_OK|MB_ICONERROR);
}
}
// Заполнить таблицу из списка
void CMusicDlg::FillTable()
{
// Чистим список
m_list1.DeleteAllItems();
// Добавляем элементы в список
if (!m_songs.Empty())
{
m_songs.Reset();
int n = 0;
do
{
Song* s = m_songs.Current();
m_list1.InsertItem(n, s->GetGenre());
m_list1.SetItemText(n, 1, s->GetArtist());
m_list1.SetItemText(n, 2, s->GetName());
m_list1.SetItemText(n, 3, s->GetAlbum());
CString year;
year.Format("%i", s->GetYear());
m_list1.SetItemText(n, 4, year);
m_list1.SetItemData(n, (DWORD)s);
n++;
}
while (m_songs.Next());
}
}
// Выделить строку таблицы
void CMusicDlg::SelectRow(Song* s)
{
int count = m_list1.GetItemCount();
for (int i = 0; i < count; i++)
{
DWORD data = m_list1.GetItemData(i);
if (data == (DWORD)s)
{
m_list1.SetItemState(i, LVIS_SELECTED, LVIS_SELECTED);
m_list1.EnsureVisible(i, TRUE);
break;
}
}
}
RingList.h
#pragma once

- Дольмены
- Доля депозитных операций в структуре пассивов
- Домашнее насилие
- Домашнее хозяйстао как субъект рыночных отношений
- Домашнее хозяйство
- Домашнее хозяйство в современной экономической системе
- Домашнее хозяйство (домохозяйство)
- Доллар и евро как мировые валюты
- Доллар и его роль в современной валютной системе
- Доллар и его роль в современной валютной системе
- "Долларизация" переходных экономик как фактор роста цен
- Долларизация: причины и предпосылки, понятие, виды, последствия
- Доллар Соединенных Штатов Америки
- Доллар США