Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
KR_po_IF.docx
Скачиваний:
17
Добавлен:
14.06.2017
Размер:
52.89 Кб
Скачать
  1. Заключение

При выполнении данной курсовой работы были получены навыки разработки многомодульных программ. Были освоены приемы создания псевдографического интерфейса, изучены функции работы с консолью, способы обработки событий от клавиатуры и мыши. Усвоены механизмы реализации меню. Изучены функции работы с файлом. Получены базовые навыки программирования на языке С. Изучены основные возможности среды программирования Visual Studio 2017. Получены навыки отладки и тестирования программ.

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

Не удалось реализовать панель инструментов, т.к. псевдографический интерфейс накладывает ограничения на интерфейс программы.

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

Список используемых источников

  1. Керниган Б. Ритчи Д. Язык программирования С. 1985 г.

  2. К. Джамса. Учимся программировать на языке С++. 1997 г.

  3. В. Г. Давыдов. Программирование и основы алгоритмизации. 2003 г.

Приложение а

Листинг программы

#include "stdafx.h"

#include "windows.h"

HANDLE hConsoleOut; /* Дискриптор консоли для вывода */

CONSOLE_SCREEN_BUFFER_INFO csbiInfo; /* Информация о консоли */

COORD Home = { 0,5 }; /*координаты курсора - столбец, строка*/

struct Dat {

int Day;

int Month;

int Year;

};

struct Person {

char Name[80]; //ФИО абонента

char TelNom[14]; //Телефонный номер

struct Dat Podkl; //Дата подключения

char Adr[120]; //Адрес абонента

};

struct Person Sotr, *pS;//Объявляем структуру данных и указатель

FILE * pIN, *pOut;//Указатели для работы с файлами

char NameFile[] = "..\\MyBD.dat";

char NameOldFile[] = "..\\MyBD.Old";//Копия файла до изменений

int NRec;//количество записей

void ClearScreen(void) //Функция очистки консоли и установки курсора

{

//получаем информацию о консоли

hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);

GetConsoleScreenBufferInfo(hConsoleOut, &csbiInfo);

::system("cls"); //очищаем консоль

//устанавливаем курсор в позицию Home

::SetConsoleCursorPosition(hConsoleOut, Home);

}

int FileCopy()

{

errno_t err;//переменная для проверки на ошибки

//int k = sizeof(NRec) + sizeof(Sotr)*NRec;//размер файла в байтах

err = fopen_s(&pOut, NameOldFile, "wb");

if (err == 0)

{

int D=NRec;

fwrite(&NRec, sizeof(NRec), 1, pOut);

fseek(pIN, sizeof(NRec), 0);

while (D-- > 0)

{

//fseek(pIN, sizeof(NRec), 0);

fread(&Sotr, sizeof(Sotr), 1, pIN);

fwrite(&Sotr, sizeof(Sotr), 1, pOut);

}

}

else

{

printf("Не удается создать файл для копии\n");

return 1;

}

fclose(pOut);

return 0;

}

void PrintSotr(int N) {

ClearScreen();

printf("Печать %d записи \n", N);

printf("1.ФИО абонента - %s\n", Sotr.Name);

printf("2.Телефонный номер - %s\n", Sotr.TelNom);

printf("3.Дата подключения - %d/%d/%d\n", Sotr.Podkl.Day,

Sotr.Podkl.Month, Sotr.Podkl.Year);

printf("4.Адрес - %s\n", Sotr.Adr);

::system("pause");

}

void AddRec()

{

fseek(pIN, sizeof(NRec)+sizeof(Sotr)*NRec, 0);

fwrite(&Sotr, sizeof(Sotr), 1, pIN);

NRec++;

fseek(pIN, 0, 0);

fwrite(&NRec, sizeof(NRec), 1, pIN);

}

void VvodDat() {

int LEAP;

printf("Введите год=>");

scanf_s("%d", &Sotr.Podkl.Year);

int Y = Sotr.Podkl.Year;

LEAP = Y % 4 == 0 && Y % 100 != 0 || Y % 400 == 0;

printf("Введите месяц=>");

scanf_s("%d", &Sotr.Podkl.Month);

while (Sotr.Podkl.Month < 1 || Sotr.Podkl.Month>12)

{

printf("Неверное значение месяца! ВВедите вновь!=>");

scanf_s("%d", &Sotr.Podkl.Month);

}

printf("Введите день=>");

scanf_s("%d", &Sotr.Podkl.Day);

int MaxDay = 31; int M = Sotr.Podkl.Month;

if (M == 2) MaxDay = 28 + LEAP;

if (M == 4 || M == 6 || M == 9 || M == 11) MaxDay = 30;

while (Sotr.Podkl.Day<1 || Sotr.Podkl.Day>MaxDay)

{

printf("Неверный день для месяца %d\nВведите вновь=>", M);

scanf_s("%d", &Sotr.Podkl.Day);

}

}

void Vvod(/*int N */)//N-номер записи в файле

{

ClearScreen();

printf("Ввод записи об абоненте\n");

printf("Введи ФИО абонента=>");

scanf_s("%39s", Sotr.Name, sizeof(Sotr.Name));

printf("Введи телефонный номер абонента=>");

scanf_s("%39s", Sotr.TelNom, sizeof(Sotr.TelNom));

printf("Введи дату подключения\n");

VvodDat();

printf("Введи адрес=>");

scanf_s("%39s", &Sotr.Adr, sizeof(Sotr.Adr));

AddRec();

}

int ConnectBD() {

errno_t err;//переменная для проверки на ошибки

int k;

err = fopen_s(&pIN, NameFile, "r+b");

if (err != 0) {

printf("Не удалось окрыть файл! Создать новый? Да=1, Нет=0\n=>");

scanf_s("%d", &k);

if (k == 0) return 1;//отказ от создания нового файла

else

{//создание нового файла

err = fopen_s(&pIN, NameFile, "wb");

if (err == 0) {

NRec = 0;

fwrite(&NRec, sizeof(NRec), 1, pIN);

return 0;

}

else {

printf("Не удалось создать файл\n");

return 2;

}

}

}

fread(&NRec, sizeof(NRec), 1, pIN);//чтение количества записей в переменную NRec

return 0;

}

int Menu()

{

ClearScreen();//вызов функции очистки консоли

int t;

printf("\t\t1. Посмотреть записи\n");

printf("\t\t2. Добавить записи\n");

printf("\t\t3. Удалить запись\n");

printf("\t\t4. Исправить запись\n");

printf("\t\t5. Завершить работу БД\n");

printf("\t\t Выбери номер для работы =>");

//запоминаем состояние буфера консоли

GetConsoleScreenBufferInfo(hConsoleOut, &csbiInfo);

scanf_s("%d", &t);

while (t < 1 || t>5)//обработка неверного номера пункта меню

{

//сохраняем координаты курсора для повторного ввода

COORD Home = { csbiInfo.dwCursorPosition.X + 2, csbiInfo.dwCursorPosition.Y };

::SetConsoleCursorPosition(hConsoleOut, Home);

printf("Неверно! попробуйте вновь!");

Sleep(3000);//Задержка на 3 секунды

Home.X -= 2;

::SetConsoleCursorPosition(hConsoleOut, Home);

printf(" ");

::SetConsoleCursorPosition(hConsoleOut, Home);

scanf_s("%d", &t);

}

return t;

}

void LookRec()//просмотр записей

{

ClearScreen();

Home = { 5,2 };

::SetConsoleCursorPosition(hConsoleOut, Home);

printf("Введите номер записи для просмотра\n");

int k;

scanf_s("%d", &k);

while (k<1 || k>NRec)//нет такой записи

{

printf("Такой записи нет в БД.Введите другой номер");

scanf_s("%d", &k);

}

//установка курсора на нужную запись

fseek(pIN, sizeof(NRec) + sizeof(Sotr)*(k - 1), 0);

fread(&Sotr, sizeof(Sotr), 1, pIN);//чтение записи в структуру Sotr

PrintSotr(k);//Вывод прочитанной записи

}

int DeleteRec()

{

printf("Введите номер удаляемой запис=>");

int N,k;

scanf_s("%d", &N);

while (N <1 && N > NRec)

{

printf("Такой записи нет. Введите другой номер=>");

scanf_s("%d", &N);

}

fseek(pIN, sizeof(NRec) + sizeof(Sotr)*(N - 1), 0);

fread(&Sotr, sizeof(Sotr), 1, pIN);//чтение записи в структуру Sotr

PrintSotr(N);

printf("Запись %d будет удалена навсегда!!!Для подтверждения Да=1, Нет=0",N);

scanf_s("%d", &k);

if (k == 0) return 1;

while (N<NRec)

{

fseek(pIN, sizeof(Sotr)*N + sizeof(NRec), 0);

fread(&Sotr, sizeof(Sotr), 1, pIN);

fseek(pIN, sizeof(Sotr)*(N - 1) + sizeof(NRec), 0);

fwrite(&Sotr, sizeof(Sotr), 1, pIN);

N++;

}

NRec--;

fseek(pIN, 0, 0);

fwrite(&NRec, sizeof(NRec), 1, pIN);

return 0;

}

int DelRec()

{

::system("Cls");

printf("\t\tУдаление записей\n");

int k,m;

printf("Создать резервную копию? Да=1, нет=0\n");

scanf_s("%d", &k);

if (k != 0)

if (!FileCopy())

{

printf("Копия создана!\n");

return DeleteRec();

}

else {

printf("Не удалось создать копию!!!\n Все равно продолжить? Да=1, нет=0\n");

scanf_s("%d", &m);

if (m == 0)

{

printf("Не выполняем удаление!!!\n");

return 1;

}

else

return DeleteRec();

}

return DeleteRec();

}

void Izmenit(int m){

switch (m)

{

case 1: {

printf("Ведите новое значение для фамилии\n");

scanf_s("%39s", Sotr.Name, sizeof(Sotr.Name));

break;

}

case 2: {

printf("Введи телефонный номер=>");

scanf_s("%39s", Sotr.TelNom, sizeof(Sotr.TelNom));

break;

}

case 3: {

printf("Введи дату подключения\n");

VvodDat();

break;

}

case 4: {

printf("Введи адрес=>");

scanf_s("%39s", Sotr.Adr, sizeof(Sotr.Adr));

break;

}

}

}

void RecEdit()

{

//функция редактирования записи

int k;//номер записи

int m;//номер пункта

::system("cls");

printf("Введи номер записи для редактирования =>");

scanf_s("%d", &k);

while (k < 1 || k > NRec) {

printf("Неверный номер записи. Введи заново\n");

scanf_s("%d", &k);

}

fseek(pIN, sizeof(NRec) + sizeof(Sotr)*(k - 1), 0);

fread(&Sotr, sizeof(Sotr), 1, pIN);

while (1) {

PrintSotr(k);

printf("Выбери номер пункта для исправления или 0 для окончания");

scanf_s("%d", &m);

while (m < 0 || m>4)//всего 4 поля в структуре Sotr

{

printf("число должно быть от 0 до 4!Введите вновь!\n");

scanf_s("%d", &m);

}

if (m > 0 && m < 5)

//изменения в записи

Izmenit(m);

if (m == 0)//конец редактирования

{

printf("Сохранить изменения? Да-1 нет-0=>");

scanf_s("%d", &m);

if (m == 0) return;

fseek(pIN, sizeof(NRec) + sizeof(Sotr)*(k - 1), 0);

fwrite(&Sotr, sizeof(Sotr), 1, pIN);

return;

}

}

}

int main()

{

::system("CHCP 1251");

int m;

int k = ConnectBD();//открываем файл с БД для чтения и записи

if (k != 0) return k;//аварийное завершение программы

printf("файл БД готов к работе\nВ БД записей=%d\n ",NRec);

::system("pause");

while (k = Menu())//цикл продолжается до тех пор, пока не выбран 5 пункт

{

switch (k)

{

case 1:

LookRec(); break;

case 2:

Vvod(); break;

case 3://вызов функции удаления записи

{

m = DelRec();

if (m != 0) printf("Запись не удалена\n");

::system("pause"); break;

}

case 4://вызов функции исправления записи

RecEdit(); break;

case 5:

fclose(pIN); return 0;//завершение работы

default:

break;

}

}

::system("pause"); return 0;

}