Автоматизация процесса начисления стипендий

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
    ,
    Формат файла:
    MS Word
    1,05 Мб
  • Опубликовано:
    2015-02-13
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Автоматизация процесса начисления стипендий

МИНИСТЕРСТВО ОБРАЗОВАНИЯ РЕСПУБЛИКИ БЕЛАРУСЬ

УЧРЕЖДЕНИЕ ОБРАЗОВАНИЯ «БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ»

КАФЕДРА: Экономической информатики

ФАКУЛЬТЕТ: Инженерно-экономический








ПОЯСНИТЕЛЬНАЯ ЗАПИСКА

к курсовому проекту по курсу: «Основы конструирования программ»

НА ТЕМУ: «Автоматизация процесса начисления стипендий»










МИНСК 2014

ЗАДАНИЕ К КУРСОВОМУ ПРОЕКТУ

Создать файл, содержащий сведения о результатах сдачи студентами сессии. Структура записи: номер группы, ФИО, оценки по 3 предметам, признак участия в общественной работе: 1 -активное участие, 0 - неучастие. Программа должна начислять студентам группы Х стипендию. При этом: отличники и общественники получают 50% надбавки, а просто отличники получают 25%. Студент-общественник с одной тройкой также получает стипендию.

ВВЕДЕНИЕ

Язык Си, созданный Денисом Ритчи в начале 70-х годов в Bell Laboratory американской корпорации AT&T, является одним из универсальных языков программирования. Язык Си считается языком системного программирования, хотя он удобен и для написания прикладных программ.

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

простую языковую базу, из которой вынесены в библиотеки многие существенные возможности, вроде математических <#"791927.files/image001.gif">

Рисунок 4.1 - Блок-схема алгоритма добавления элемента в начало двусвязного списка

4.2 Алгоритм удаления информации о студенте из двусвязного списка по индексу

Данный алгоритм реализуется в виде функции voidrem(intindex).

void rem(int index) {(size == 0) {("Списокпуст!\n");("pause");

} else if(index == 1 && index!= size) {*temp = first;>next->prev = NULL;= first->next;temp;-;

} else if(index == size && index!=1) {*temp = last;>prev->next = NULL;= last->prev;temp;-;

} else if(index == size && index == 1) {first;= NULL;= NULL;-;

} else if(index > 1 && index < size) {*current = first;(int i=1; i<index; i++) {= current->next;

}>prev->next = current->next;>next->prev = current->prev;

delete current;-;

};

}

Сперва проверяется размерность списка. Если список пуст, то на экран выводится предупреждение. Если список не пуст, то следует проверка, удаляется ли первый элемент. Если это так, то необходимы следующие действия:

указатель на временный узел инициализируется указателем на первый узел;

снимается связанный с первым элементом указатель на предыдущий;

далее назначается первым элементом следующий за ним элемент;

удаляется временный элемент;

размер уменьшается на единицу.

Если предыдущее условие не выполняется, то следует проверка на удаление последнего элемента. Если она выполняется, то:

указатель на временный элемент инициализируется указателем на последний узел;

снимается связанный с последним элементом указатель наследующий;

далее назначается последним элементом идущий перед ним элемент;

удаляется временный элемент;

размер уменьшается на единицу.

Если предыдущее условие не выполняется, то происходит проверка на удаление единственного элемента из списка. Если это так, то:

удаляется первый элемент;

указатель на первый элемент приравнивается NULL;

указатель на последний элемент приравнивается NULL;

размер уменьшается на единицу.

Если и это условие не выполняется, то происходит проверка, удаляется ли элемент из середины списка. Если условие выполняется, то необходимы следующие действия:

указатель на текущий узел инициализируется первым;

в цикле от i=1 до i<index с шагом инкрементации, равным единице, перемещаемся по списку через указатель на следующий узел от текущего;

обнуляем связанные с элементов указатели;

удаляем текущий узел;

уменьшаем размер на единицу.

Если условие не выполняется, то функция прекращает свою работу.

Рисунок 4.2 - Алгоритм удаления записи из двусвязного списка по индексу

4.3 Алгоритм фильтрации данных о студентах по имени

Данный алгоритм реализуется с помощью функции voidfilter_name().

void filter_name() {(size == 0) {("cls");("Списокпуст!\n");

} else {*current = first;i = 1;s;.enter_name();("cls");(" # | Группа | ФамилияИмяОтчество | О.1 | О.2 | О.3 | Соц |\n");("----|--------|-------------------------------------|-----|-----|-----|-----|\n");(current != NULL) {stud = current->data;(strcmp(s.name, stud.name)==0) {("%3d | %6s | %35s | %3d | %3d | %3d | %3s |\n", i, stud.group, stud.name, stud.mark[0], stud.mark[1],.mark[2], stud.social?"Да":"Нет");

}++;= current->next;

}("----|--------|-------------------------------------|-----|-----|-----|-----|\n");

}

};

Рисунок 4.3 - Алгоритм фильтрации данных о студентах по имени

Сперва проверяется, пустой список или нет. Если пустой, то выводится предупреждение, если нет, выполняется следующая последовательность действий:

значению текущего узла присваивается указатель на первый узел;

вводится переменная i, равная единице;

объявляется структура s типа student;

вызывается функция для ввода пользователем имени студента;

выводится на экран шапка таблицы;

при помощи цикла происходит проход по списку, если имя записи совпадает с введённым, то запись попадает в таблицу;

наращивается счётчик i на единицу происходит перемещение по списку через указатель на следующий узел;

выводится окончание таблицы.

5. ОПИСАНИЕ ПРОГРАММЫ

Прежде всего, чтобы начать работы с системой, мы должны выполнить авторизацию. Для этого предназначена функция authorize, которая принимает параметры права (пользователь либо администратор) и предлагает ввести логин и пароль. Далее сверка с данными в файле. В случае, если пользователь не забанен и такие данные существуют, то открывается доступ к работе с данными. Если же эти условия не выполняются, то выводится сообщение о том, что данные введены неправильно. В данной программе содержится 2 типа пользователей: обычные пользователи и администратор. В дальнейшем, всё зависит от прав, пользователь имеет возможность выполнять либо набор обычного пользовательского функционала, предоставленного пользовательским меню (выбрать файл для работы с данными, просмотреть все записи, выполнить задачу, поиск и фильтрация данных, выход из учётной записи), либо набор администраторского функционала, предоставляемого меню администратора (выбрать файл для работы с данными, добавить запись, отредактировать запись, удалить запись, посмотреть все записи, поиск и фильтрация данных, управление пользователями, выход из учётной записи).

Первое и второе меню первым пунктом предлагают выбрать файл для работы. Для этого необходима функция char* choose_file(), она открывает имеющийся с таким именем файл или создаёт новый файл с указанным именем. При помощи двух двусвязных списков, хранящих информацию о студентах и пользователях, происходит взаимодействие данных с файлом. За счёт реализованных в списках функций есть возможность добавлять, удалять, редактировать, фильтровать записи, получать данные и размер списка, очищать список и другое. Сами же эти функции описаны внутри структуры, которая описывает сам список.

Главным пунктом меню стоит считать пункт «Выполнить задачу», так как именно он решает поставленную задачу. Для выполнения этого пункта реализована функция void complete_target(). Она работает со списком имеющихся студентов, определённых степенью активности и группой, высчитывает средний балл из трёх имеющихся и в зависимости от этого начисляет стипендию в том или ином размере.

Логику программы можно разделить на следующие блоки: по праву - работа администратора и работа пользователя, по данным - работа с пользователями и работа со студентами.

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

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

При запуске программы пользователю предлагается сперва предлагается три варианта: войти как администратор, войти как пользователь, выход.

Рисунок 5.1 - Меню первого уровня

Рассмотрим случай выбора работы в качестве администратора. После ввода логина и пароля в случае нахождения таковых в файле предлагается выбрать файл для работы с данными.

Рисунок 5.2 - Выбор файла для работы

В результате на экране появится меню с функционалом, доступным администратору.

Рисунок 5.3 - Меню администратора

При выборе добавления записи последовательно предлагает ввести Ф.И.О., номер группы, три отметки и определить, является ли студент активистом. После этого администратор вновь выходит в меню.

Выберем просмотр всех записей. На экране появилась табличка с добавленным ранее пользователем.

Рисунок 5.4 - Вывод данных на экран

Далее добавим ещё одного студента с неактивной общественной позицией и выберем пункт меню «Фильтрация и поиск», в качестве параметра поиска будем принимать неактивных студентов группы 222223. В результате на экране появится таблица с добавленным нами пользователем.

Рисунок 5.5 - Фильтрация и поиск данных

При этом при выводе всех студентов на экран получим следующую таблицу:

Рисунок 5.6 - Вывод данных о студентах

Если мы войдём в систему в качестве пользователя, воспользуемся уже заполненным файлом и решим узнать о стипендиях, то в группе 111112 будут следующие данные начисления стипендии:

Рисунок 5.7 - Начисление стипендии студентам

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

ЗАКЛЮЧЕНИЕ

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

Программа удовлетворяет поставленным изначально условиям: реализована возможность работы двух видов пользователей с разным уровнем прав и доступа (администратор и обычный пользователь), при этом поддерживается авторизация пользователей с вводом логина и пароля, пароль шифруется; использована работа с файлами (чтение, запись); в программе используются структуры для описания сущностей, а также двусвязные списки для работы с набором данных; имеются меню нескольких уровней; используются встроенные функции для работы со строками; предусмотрена обработка ситуаций ввода неверных данных. Данные выводятся на экран в виде таблицы, код оформлен в соответствии с Code Convension.

Решена задача, поставленная в условии: формируется список студентов для начисления стипендии, зависящей от их учебных достижений и общественной активности. Интерфейс программы поддерживает русский язык.

СПИСОК ИСПОЛЬЗОВАННЫХ ИСТОЧНИКОВ

1.   Кормен, Т. Алгоритмы: учебник / Т. Кормен [и др.].: Москва - Санкт-Петербург - Киев 2005. - 1290 с.

2.      С. Панасенко - Алгоритмы шифрования - СПб.: БХВ-Петербург, 2009

.        Дейтел, П. Дж. Как програмировать на Си / учебник: Бином-Пресс, 2009. - 994 с.

.        Б. Керниган, Д. Ритчи - Язык программирования Си - Вильямс, 2009

.        Р. Хэзфилд - Искусство программирования на С- Диа-Софт, 2001

6.      Wikipedia [Электронный ресурс]. - <#"791927.files/image011.gif">

Рисунок 1 - Блок-схема алгоритма добавления элемента в начало двусвязного списка

Рисунок 2 - Алгоритм удаления записи из двусвязного списка по индексу

Рисунок 3 - Алгоритм фильтрации данных о студентах по имени

ПРИЛОЖЕНИЕ Б

Листинг кода

#pragma once

//структура с данными о студенте

{

//группаgroup[7];

//фиоname[35];

//3 оценки[3];

//активист или нетsocial;

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

void change() {

char symbol;

do {

//вывод на экран текущих данных("cls");(" Группа | Фамилия Имя Отчество | О.1 | О.2 | О.3 | Соц |\n");

printf("--------|-------------------------------------|-----|-----|-----|-----|\n");(" %6s | %35s | %3d | %3d | %3d | %3s |\n", group, name, mark[0], mark[1], mark[2], social?"Да":"Нет");("--------|-------------------------------------|-----|-----|-----|-----|\n\n");

//меню("1) Изменить Ф.И.О.\n");

printf("2) Изменить группу\n");("3) Изменить оценки\n");("4) Изменить социальную активность\n");("0) Вернуться в главное меню\n");

printf(">: ");(stdin);("%c", &symbol);

//просто вызов соответствующих функций ввода информации

switch(symbol) {'1':_name();;'2':_group();;'3':_mark();;'4':_social();;:;

}

} while(symbol != '0');

}

//вводФИОenter_name() {("cls");("ВведитеФ.И.О.\n");

printf(">: ");(stdin);

//используем для того, чтобы не набрать больше 35 символов

gets_s(name, 35);(name, name);

}

//ввод группыenter_group() {{("cls");("Введите группу\n");

printf(">: ");(stdin);

//тоже самое с fgets, не больше 7 символов

fgets(group, 7, stdin);[strlen(group)]='\0';

//проверка на длину

if(strlen(group)>=6) {

break;

}

} while(true);

}

//ввод оценкиenter_mark() {("cls");

//циклна 3 оценки(int i=0; i<3; i++) {

do{("Введите оценку #%d", (i+1));

printf(">: ");(stdin);("%d", &mark[i]);

//проверка что больше или равно 4 и меньше или равно 10

if(mark[i] >= 4 && mark[i] <= 10) {;

}

} while(true);

}

}

//ввод активист или нетenter_social() {symbol;{("cls");("1) Активист\n");

printf("0) Не активист\n");(">: ");

fflush(stdin);("%c", &symbol);(symbol) {'1':= true;='\0';;'0':= false;='\0';;:;

}

} while(symbol!='\0');

}

};

#pragma once

#include "student.h"

#define MIN_INCOME 400000

//узел списка, двусвязногоnode {

//данные узлаdata;

//указатель на предыдущий*prev;

//указатель на следующий*next;

};student_list {

//указатель на первый элемент*first;

//указатель на последний элемент*last;

//размерсписка;

//функция для начальной инициализации

void init() {= 0;= NULL;

last = NULL;

}

//добавление в начало списка

void add_front(student pdata) {

//если список пуст(size == 0) {

//выделяем память= new node();

//записываем данные>data = pdata;

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

first->next = NULL;>prev = NULL;

//последний он же будет и первым= first;

//увеличиваем размер++;

}

//если список не пуст{

//выделяем память*temp = newnode();

//записываем данные>data = pdata;

//указатель на след теперь указываем на первый

temp->next = first;

//предыдущегонет>prev = NULL;

//указатель на предыдущий первого элемента указывает на новый элемент>prev=temp;

//новый элемент становится первым= temp;

//увеличиваем размер++;

};

}

//добавление в конец спискаadd_back(student pdata) {

//если список пуст(size == 0) {

//выделяем память= new node();

//записываемданные>data = pdata;

//указатели на пред и след не существуют

last->next = NULL;>prev = NULL;

//первый он же последний= last;

//увеличиваем размер++;

}

//если список не пуст{

//выделяемпамять*temp = newnode();

//записываем данные>data = pdata;

//указатель на предыдущий нового элемента указывает на последний элемент>prev = last;

//указатель на след нового элемента пуст>next = NULL;

//указатель на следующий последнего указывает теперь на новый элемент>next = temp;

//новый элемент теперь последний= temp;

//увеличиваем размер++;

};

}

//функция дял удаления по индексуrem(int index) {

//если удалять нечего, то выводи на экран предупреждение

if(size == 0) {("Списокпуст!\n");

system("pause");

//если удаляем первый элемент

} else if(index == 1 && index!= size) {

//запоминаем его указатель*temp = first;

//снимаем связанный с первым элементом указатель на предыдущий>next->prev = NULL;

//теперь первый элемент - это следующий за первым= first->next;

//удаляем запомненный первый элементtemp;

//уменьшаем размер-;

//если удаляем последний, то примерно тоже самое происходит

} else if(index == size && index!=1) {*temp = last;>prev->next = NULL;= last->prev;temp;

size--;

//если удаляем элемент, который является единственным в списке

} else if(index == size && index == 1) {

//просто удаляемfirst;

//обнуляем указатели на первый и последний элементы

first = NULL;= NULL;

//уменьшаемразмер-;

//если удаляем из середины списка

} else if(index > 1 && index < size) {*current = first;

//в цикле проходим от начала списка до нужного места

for(int i=1; i<index; i++) {

current = current->next;

}

//обнуляем связанные с элементмо указатели

current->prev->next = current->next;>next->prev = current->prev;

//удаляем элементcurrent;

//уменьшаем размер-;

};

}

//функция получение элемента из списка

student get(int index) {*current = first;

//проходим по циклу до нужного элемента

for(int i=1; i<index; i++) {= current->next;

}

//возвращаем содержимое узлаcurrent->data;

}

//размер спискаget_size() {

//возвращаем размер спискаsize;

}

//функция изменения элемента списка

voidchange(intindex) {

//проверка на индексы(index<= 0 || index>size) {

printf("Неверный индекс!\n");("pause");

//на размер списка

} else if(size == 0) {("Списокпуст!\n");

system("pause");

//если изменяем первый, то вызываем функция изменения из структуры со студентом

} else if(index == 1 ) {>data.change();

//если последний, то точно также

} else if(index == size) {>data.change();

//если где-то посередине списка

} else if(index > 1 && index < size) {

node *current = first;

//проходим в цикле до нужного элемента

for(int i=0; i<index; i++) {

current = current->next;

}

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

current->data.change();

}

}

//функция распечатки

voidprint() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node *current = first;i = 1;("cls");(" # | Группа | ФамилияИмяОтчество | О.1 | О.2 | О.3 | Соц |\n");("----|--------|-------------------------------------|-----|-----|-----|-----|\n");(current != NULL) {stud = current->data;("%3d | %6s | %35s | %3d | %3d | %3d | %3s |\n", i, stud.group, stud.name, stud.mark[0], stud.mark[1],.mark[2], stud.social?"Да":"Нет");++;= current->next;

}("----|--------|-------------------------------------|-----|-----|-----|-----|\n");

}

}

//функция очистки спискаclear() {

//если есть что очищать(size > 0) {

//в цикле вызываем функцию удаления по индексу

for(int i=1; i<=size; i++) {

rem(i);

}

}

}_soc() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node *current = first;i = 1;s;.enter_social();("cls");(" # | Группа | ФамилияИмяОтчество | О.1 | О.2 | О.3 | Соц |\n");("----|--------|-------------------------------------|-----|-----|-----|-----|\n");(current != NULL) {stud = current->data;(s.social == stud.social) {("%3d | %6s | %35s | %3d | %3d | %3d | %3s |\n", i, stud.group, stud.name, stud.mark[0], stud.mark[1],.mark[2], stud.social?"Да":"Нет");

}++;= current->next;

}("----|--------|-------------------------------------|-----|-----|-----|-----|\n");

}

};filter_soc_group() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node *current = first;i = 1;s;.enter_social();.enter_group();("cls");(" # | Группа | ФамилияИмяОтчество | О.1 | О.2 | О.3 | Соц |\n");("----|--------|-------------------------------------|-----|-----|-----|-----|\n");(current != NULL) {stud = current->data;(strcmp(s.group, stud.group)==0 && s.social == stud.social) {("%3d | %6s | %35s | %3d | %3d | %3d | %3s |\n", i, stud.group, stud.name, stud.mark[0], stud.mark[1],.mark[2], stud.social?"Да":"Нет");

}++;= current->next;

}("----|--------|-------------------------------------|-----|-----|-----|-----|\n");

}

};filter_soc_excellent() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node *current = first;i = 1;("cls");(" # | Группа | ФамилияИмяОтчество | О.1 | О.2 | О.3 | Соц |\n");("----|--------|-------------------------------------|-----|-----|-----|-----|\n");(current != NULL) {stud = current->data;avg = stud.mark[0] + stud.mark[1] + stud.mark[2];/=3;(stud.social && avg >= 8) {("%3d | %6s | %35s | %3d | %3d | %3d | %3s |\n", i, stud.group, stud.name, stud.mark[0], stud.mark[1],.mark[2], stud.social?"Да":"Нет");

}++;= current->next;

}("----|--------|-------------------------------------|-----|-----|-----|-----|\n");

}

};filter_group() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node *current = first;i = 1;s;.enter_group();("cls");(" # | Группа | ФамилияИмяОтчество | О.1 | О.2 | О.3 | Соц |\n");("----|--------|-------------------------------------|-----|-----|-----|-----|\n");(current != NULL) {stud = current->data;(strcmp(s.group, stud.group)==0) {("%3d | %6s | %35s | %3d | %3d | %3d | %3s |\n", i, stud.group, stud.name, stud.mark[0], stud.mark[1],.mark[2], stud.social?"Да":"Нет");

}++;= current->next;

}("----|--------|-------------------------------------|-----|-----|-----|-----|\n");

}

};filter_name_group() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node *current = first;i = 1;s;.enter_name();.enter_group();("cls");(" # | Группа | ФамилияИмяОтчество | О.1 | О.2 | О.3 | Соц |\n");("----|--------|-------------------------------------|-----|-----|-----|-----|\n");(current != NULL) {stud = current->data;(strcmp(s.name, stud.name)==0 && strcmp(s.group, stud.group)==0) {("%3d | %6s | %35s | %3d | %3d | %3d | %3s |\n", i, stud.group, stud.name, stud.mark[0], stud.mark[1],.mark[2], stud.social?"Да":"Нет");

}("----|--------|-------------------------------------|-----|-----|-----|-----|\n");

}

};complete_target() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node *current = first;i = 1;s;.enter_group();("cls");("# | Группа | Фамилия Имя Отчество | %-7s | Соц | %-9s |\n", "Ср.балл", "Стипендия");("---|--------|-------------------------------------|---------|-----|-----------|\n");(current != NULL) {stud = current->data;(strcmp(stud.group, s.group)==0) {income;avg = stud.mark[0] + stud.mark[1] + stud.mark[2];/=3;(avg > 4) {= MIN_INCOME;(avg>= 8 &&stud.social) {+= MIN_INCOME/2;

} else if(avg >= 8) {+= MIN_INCOME/4;

}

} else {= 0;

}("%2d | %6s | %35s | %-7d | %3s | %-9d |\n", i, stud.group, stud.name, avg,.social?"Да":"Нет", income);

}++;= current->next;

}("---|--------|-------------------------------------|---------|-----|-----------|\n");

}

};

};

#pragma once

//структура с данными о пользователе

struct user_data

{

//логинlogin[15];

//пароль[15];

//права доступа[6];

//забанен или нетactive;

//функция для начальной инициализации

void init(char *prights) {

strcpy(rights, prights);= true;

}

//вводлогинаenter_login() {("cls");

printf("Введите логин. Помните, что максимальная длина логина 15 символов!\n");(">: ");(stdin);

//через fgets чтобы не набрать больше 15 символов

fgets(login, 15, stdin);[strlen(login)-1]='\0';

}

//вводпароляenter_password() {symbol;index = 0;("cls");("Введите пароль. Помните, что максимальная длина пароля 15 символов!\n");(">: ");

{

//читаем посимвольно(stdin);

symbol = _getch();(symbol)

{8:

//если клавиша удаления, удаляем последний символ с консоли

if(index > 0) {("\b \b");

index--;

};13:

//если enter, то ставим ноль-символ

password[index] = '\0';;

default:

//если что-то другое, то сохраняем введенный символ и выводим на экран звездочку

password[index] = symbol;[index+1] = '\0';

_putch('*');++;;

}

} while(symbol != 13 && index < 15);

//в конце ввода шифруем пароль();

}

//шифрование пароляencrypt() {*result = new char[strlen(password)];

int hash = 0;

//умножаем длину пароля на 11= 11 * strlen(password);

//прибавляем к полученному ранее результату код каждого символа, умноженный на 11

for(int i=0; i<strlen(password)-1; i++) {

hash *= 11 * password[i];

}

//из инта переделываем в char, в 16-ричной системе счисления, таким образом получаем зашифрованный пароль

_itoa(hash, result, 16);

//копируем зашифрованный пароль

strcpy(password, result);

}

};

#pragmaonce

#include "user_data.h"

//узелсписка, двусвязного_user_data {

//данные узла_datadata;

//указатель на предыдущий

node_user_data *prev;

//указатель наследующий

node_user_data *next;

};user_data_list {

//указатель на первый элемент_user_data *first;

//указатель на последний элемент

node_user_data *last;

//размер списка

int size;

//функция для начальной инициализации

void init() {= 0;= NULL; = NULL;

}

//добавление в начало списка

void add_front(user_data pdata) {

//если список пуст(size == 0) {

//выделяем память= new node_user_data();

//записываем данные>data = pdata;

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

first->next = NULL;>prev = NULL;

//последний он же будет и первым= first;

//увеличиваем размер++;

}

//если список не пуст{

//выделяем память_user_data *temp = new node_user_data();

//записываем данные>data = pdata;

//указатель на след теперь указываем на первый

temp->next = first;

//предыдущего нет>prev = NULL;

//указатель на предыдущий первого элемента указывает на новый элемент>prev=temp;

//новый элемент становится первым= temp;

//увеличиваем размер++;

};

}

//добавление в конец спискаadd_back(user_data pdata) {

//если список пуст(size == 0) {

//выделяем память= new node_user_data();

//записываем данные>data = pdata;

//указатели на пред и след не существуют

last->next = NULL;>prev = NULL;

//первый он же последний= last;

//увеличиваем размер++;

}

//если список не пуст

else {

//выделяем память_user_data *temp = new node_user_data();

//записываем данные>data = pdata;

//указатель на предыдущий нового элемента указывает на последний элемент>prev = last;

//указатель на след нового элемента пуст>next = NULL;

//указатель на следующий последнего указывает теперь на новый элемент>next = temp;

//новый элемент теперь последний= temp;

//увеличиваем размер++;

};

}

//функция для удаления по индексуrem(int index) {

//если удалять нечего, то выводи на экран предупреждение

if(size == 0) {("Списокпуст!\n");

system("pause");

//если удаляем первый элемент

} else if(index == 1 && index!= size) {

//запоминаем его указатель_user_data *temp = first;

//снимаем связанный с первым элементом указатель на предыдущий>next->prev = NULL;

//теперь первый элемент - это следующий за первым= first->next;

//удаляем запомненный первый элементtemp;

//уменьшаем размер-;

//если удаляем последний, то примерно тоже самое происходит

} else if(index == size && index!=1) {_user_data *temp = last;>prev->next = NULL;= last->prev;

delete temp;-;

//если удаляем элемент, который является единственным в списке

} else if(index == size && index == 1) {

//просто удаляемfirst;

//обнуляем указатели на первый и последний элементы

first = NULL;= NULL;

//уменьшаем размер-;

//если удаляем из середины списка

} else if(index > 1 && index < size) {

node_user_data *current = first;

//в цикле проходим от начала списка до нужного места

for(int i=1; i<index; i++) {

current = current->next;

}

//обнуляем связанные с элементно указатели

current->prev->next = current->next;>next->prev = current->prev;

//удаляем элементcurrent;

//уменьшаем размер-;

};

}

//функция получение элемента из списка

user_data&get(int index) {_user_data *current = first;

//проходим по циклу до нужного элемента

for(int i=0; i<index; i++) {= current->next;

}

//возвращаем содержимое узлаcurrent->data;

}

//размер спискаget_size() {

//возвращаем размер списка;

}

//функция распечатки() {

//если размер равен 0, то выводим предупреждение

if(size == 0) {("cls");("Списокпуст!\n");

} else {

//иначе рисуем красивую таблицу, проходясь в цикле по всему списку

node_user_data *current = first;i = 1;("cls");(" # | %-15s | %-15s | %-6s | %-10s |\n", "Логин", "Пароль", "Права", "Активность");("-----|-----------------|-----------------|--------|------------|\n");(current != NULL) {_data user = current->data;(" %-3d | %-15s | %-15s | %-6s | %-10s\n", i, user.login, user.password, user.rights,.active ? "Да": "Нет");++;= current->next;

}("-----|-----------------|-----------------|--------|------------|\n");

}

}

//функция очистки спискаclear() {

//если есть что очищать(size > 0) {

//в цикле вызываем функцию удаления по индексу

for(int i=1; i<=size; i++) {(i);

}

}

}

};

#include <stdlib.h>

#include <stdio.h>

#include <conio.h>

#include <locale.h>

#include <Windows.h>

#include <direct.h>

#include "student.h"

#include "user_data.h"

#include "student_list.h"

#include "user_data_list.h"

//объявление списка со студентами_list stud_list;

//выбор имени файла* choose_file();

//чтение списка со студентами из файла

void read_file(char *filename);

//запись списка со студентами в файл

void write_file(char *filename);

//функция для добавления студента в списокadd_student();

//изменение студента из списка

voidchange_student();

//удаления_student();

//вывода на экран

voidprint_student();

//функция авторизации

boolauthorize(char *rights) {

//создание структуры с пользовательскими данными

user_data auth;

//инициализацияее.init(rights);

//ввод логина.enter_login();

//ввод пароля.enter_password();

//открытие файла с пользовательскими данными и вычисление его размера

FILE *file_user_data = fopen("users.bin", "rb");(file_user_data, 0, SEEK_END);num_users = ftell(file_user_data)/sizeof(user_data);(file_user_data, 0, SEEK_SET);(int i=0; i<num_users; i++) {

user_data user;

//чтение данных из файла

fread(&user, sizeof(user_data), 1, file_user_data);

//если совпадают логины, права доступа, пароли и запись не забанена, то закрываем файл и возвращаем true

if(strcmp(auth.login, user.login)==0 && strcmp(auth.rights, user.rights)==0

&&strcmp(auth.password, user.password)==0 && user.active == true) {(file_user_data);true;

}

}

//если цикл закончен, и совпадений не найдено, то закрываем файл и возвращаем false

fclose(file_user_data);false;

}menu_rule_users() {ch;k;number;_data user;_data_list user_list;_list.init();*file = fopen("users.bin", "rb");(file, 0, SEEK_END);size = ftell(file)/sizeof(user_data);(file, 0, SEEK_SET);(int i=0; i<size; i++) {(&user, sizeof(user_data), 1, file);_list.add_back(user);

};(file);{("cls");

printf("1) Добавить пользователя\n");("2) Удалить пользователя\n");("3) Забанить пользователя\n");("4) Просмотреть пользователей\n");

printf("0) Выход\n");(">: ");(stdin);("%c", &ch);(ch) {'1':("cls");("1) Администратор\n");("0) Пользователь\n");(">: ");(stdin);("%c", &k);(k=='1') {.init("admin");

} else {.init("user");

}.enter_login();.enter_password();_list.add_back(user);;'2':{_list.print();

printf("Введите номер удаляемого элемента или 0 для выхода\n");

printf(">: ");(stdin);("%c", &k);= atoi(&k);(number != 0) {(number > 1 && number <= user_list.get_size()) {_list.rem(number);

};

};

} while(number != 0);;'3':{_list.print();

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

printf(">: ");(stdin);("%c", &k);= atoi(&k);(number != 0) {(number > 1 && number <= user_list.get_size()) {_list.get(number-1).active = !user_list.get(number-1).active;

};

};

} while(number != 0);;'4':_list.print();("pause");;:;

};

} while(ch!='0');= fopen("users.bin", "wb");(int i=0; i<user_list.get_size(); i++) {= user_list.get(i);(&user, sizeof(user_data), 1, file);

};(file);(file);

};

//меню админаmenu_admin() {ch;k;filename[25];

//выбор файла начальный(filename, choose_file());

//чтениеизфайла_file(filename);

{

//простое меню("cls");

printf("Работа происходит с файлом %s\n", filename);("1) Выбрать файл для работы с данными\n");("2) Добавить запись\n");("3) Отредактировать запись\n");("4) Удалить запись\n");("5) Просмотреть все записи\n");("6) Поиск и фильтрация данных\n");("7) Управление пользователями\n");("0) Выход из учетной записи\n");

printf(">: ");(stdin);("%c", &ch);

switch (ch)

{'1':

//если выбрали изменить файл, то записываем изменения в старый

write_file(filename);

//выбираем новый(filename, choose_file());

//читаем данные из нового

read_file(filename);

if(filename) {("Файлуспешнооткрыт!\n");("pause");

} else {("Возникли проблемы с файлом. Попробуйте снова!\n");("pause");

}

break;

//во всех других случаях вызов соответствующих функций

case '2':_student();;'3':_student();;'4':_student();;'5':_student();;'6':{("cls");

printf("1) Отфильтровать по социальной активности\n");("2) Отфильтровать по активности в группе\n");("3) Найти студентов-активистов-отличников\n");

printf("0) Выйти\n");(">: ");(stdin);("%c", &k);(k) {'1':_list.filter_soc();("pause");;'2':_list.filter_soc_group();("pause");;'3':_list.filter_soc_excellent();("pause");;:;

};

} while(k!='0');;'7':_rule_users();;:

break;

}

} while (ch!='0');

//запись изменений при выходе из меню

write_file(filename);

}

//меню пользователяmenu_user() {ch;k;filename[25];

//выбор файла начальный(filename, choose_file());

//чтение из файла_file(filename);

{

//простое меню("cls");

printf("Работа происходит с файлом %s\n", filename);("1) Выбрать файл для работы с данными\n");("2) Просмотреть все записи\n");("3) Выполнить задачу\n");("4) Поиск и фильтрация данных\n");("0) Выход из учетной записи\n");

printf(">: ");(stdin);("%c", &ch);

switch (ch)

{'1':

//если выбрали изменить файл, то записываем изменения в старый

write_file(filename);

//выбираем новый(filename, choose_file());

//читаем данные из нового

read_file(filename);

if(filename) {("Файлу спешно открыт!\n");("pause");

} else {

("Возникли проблемы с файлом. Попробуйте снова!\n");("pause");

}

break;

//во всех других случаях вызов соответствующих функций

case '2':_student();;'3':_list.complete_target();("pause");;'4':{("cls");("1) НайтипоФ.И.О.\n");

printf("2) Отфильтровать по группе\n");("3) Найти по Ф.И.О. и группе\n");

printf("0) Выйти\n");(">: ");(stdin);("%c", &k);(k) {'1':_list.filter_name();("pause");;'2':_list.filter_group();("pause");;'3':_list.filter_name_group();("pause");;:;

};

} while(k!='0');;:

break;

}

} while (ch!='0');

//запись изменений при выходе из меню

write_file(filename);

}main() {(LC_ALL, "Russian");symbol;

do

{

//меню первого уровня("cls");("1) Войти как администратор\n");("2) Войти как пользователь\n");

printf("0) Выход\n");(">: ");("%c", &symbol);

switch(symbol)

{'1':

//если авторизация прошла, то меню админа, иначе предупреждение

if(authorize("admin")) {_admin();

} else {("cls");("Проверьте комбинацию логина и пароля!\n");("pause");

};'2':

//если авторизация прошла, то меню админа, иначе предупреждение

if(authorize("user")) {_user();

} else {("cls");("Проверьте комбинацию логина и пароля!\n");("pause");

};:;

}

} while (symbol!='0');

}

//выбор имени файла* choose_file() {filename[25];

system("cls");("Введите название файла. Если такого файла не существует, то будет создан новый!\n");("Максимальная длина имени файла 25 символов!\n");(">: ");(stdin);

//fgets для контроля переполнения

fgets(filename, 25, stdin);[strlen(filename)-1]='\0';

//открываем файл для дозаписи, если его не было, то он будет создан

FILE *file = fopen(filename, "ab");(file);

//возвращаем имя файлаfilename;

}

//чтение данных из файлаread_file(char *filename) {

//открытие файла*file = fopen(filename, "rb");

//очистка списка_list.clear();

//инициализация после очистки_list.init();

//вычисление количества записей в файле(file, 0, SEEK_END);

int size = ftell(file)/sizeof(student);(file, 0, SEEK_SET);(int i=0; i<size; i++) {stud;

//чтение из файла(&stud, sizeof(student), 1, file);

//добавление в список_list.add_back(stud);

}

//закрытие файла(file);

}

//запись в файл

void write_file(char *filename) {

//открытие для записи с уничтожением содержимого

FILE *file = fopen(filename, "wb");(int i=1; i<=stud_list.get_size(); i++) {

//"достаемэлементизспсика"stud = stud_list.get(i);

//записываем его в файл(&stud, sizeof(student), 1, file);

}

//закрываем файл(file);(file);

//добавление студентаadd_student() {

//создание новой структурыstud;

//вызов функций ввода из этой структуры

stud.enter_name();.enter_group();.enter_mark();.enter_social();

//добавление структуры в список_list.add_back(stud);

}

//изменение студентаchange_student() {number;

do{

//вывод списка на экран_list.print();

//ввод номера студента для изменения("Введите номер студента для изменения. 0 - для выхода\n");(">: ");(stdin);("%d", &number);

//проверка не вылезает ли он за рамки

if(number < 0 || number > stud_list.get_size()) {("Неверный выбор!\n");("pause");

} else if (number != 0) {

//если мы не ввели 0, то вызываем функцию изменения студента из структуры со списком

stud_list.change(number);

}

} while(number!=0);

}

//удаление студента_student() {;

//все тоже самое, что и в изменении, только вызывается функция не изменения, а удаления{_list.print();("Введите номер студента для удаления. 0 - для выхода\n");(">: ");(stdin);("%d", &number);(number < 0 || number > stud_list.get_size()) {("Неверный выбор!\n");("pause");

} else if (number != 0) {_list.rem(number);

}

} while(number!=0);

}

//вывод на экран

voidprint_student() {

//вызов функции вывода на экран из структуры со списком

stud_list.print();("pause");

}


Не нашли материал для своей работы?
Поможем написать уникальную работу
Без плагиата!