Первый опыт написания полноценной программы +5


Каждый начинающий программист мечтает реализовать свой собственный проект. Не написать простенький код, по заданию преподавателя, а воплотить в жизнь свои идеи. Так и я, изучая C++ 3-4 месяца, решился попробовать разработать макет электронного журнала для преподавателей.

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

По итогу, пришел к выводу, что в программе потребуется реализовать:

  1. Регистрацию (Reg),

  2. Авторизацию (Authon),

  3. Выбор группы (GroupSelection),

  4. Возможность выставлять оценки (Grades),

  5. Возможность выставлять посещаемость (Attendance),

  6. Возможность писать комментарии к датам (Comment),

  7. Возможность устанавливать dedlin’ы (Deadline).

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

блок-схема программы
блок-схема программы

Аналогично, были созданы блок схемы для каждой функции.

авторизация
авторизация
регистрация
регистрация
выбор группы
выбор группы
выставление оценок
выставление оценок
простановка посещаемости
простановка посещаемости
написание комментариев к датам
написание комментариев к датам
установка dedlin’ов
установка dedlin’ов

Написание кода программы

Первым шагом написания программы является добавления необходимых заголовочных файлов, а именно:

  1. iostream — заголовочный файл с классами, функциями и переменными для организации ввода-вывода.

  2. string -  это заголовочный файл для взаимодействия с
    классами string (строками).

  3. fstream - заголовочный файл, включающий набор классов, методов и функций, которые предоставляют интерфейс для чтения/записи данных из/в файл.

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

std::string nameofgroup;

Чтобы удобно группировать данных в одной переменной для каждого объекта, который оперирует этими данными, мною было объявлено несколько классов, а именно:

Класс данных о преподавателе – DataofTeature.

class DataofTeature
{
public:
	std::string name; //имя преподавателя
	std::string surname; //фамилия преподавателя
	std::string patronymic; //отчество преподавателя
	std::string login; //логин преподавателя
	std::string password; //пароль преподавателя
};

Класс данных о студенте – DataofStudent.

class DataofStudent
{
public:
	std::string group; //название группы студента
	std::string name; //имя студента
	std::string surname; //фамилия студента
};

Основываясь на ранее представленных блок схемах, был написан код для всех функций. Разберемся с каждой функций подробнее.

Reg

Функция Reg реализует полноценную регистрацию, с записью данных о пользователе в текстовый файл.

В ходе выполнения функции, пользователю предлагается ввести ФИО, логин и пароль. После получения программой логина, проверяется его наличие в системе, если логин совпадает с ранее записанным в базу логинов, то пользователя предлагается ввести логин повторно. Как только программа получает ФИО, пароль и уникальный логин, происходит запись логина в базу для логинов (при открытие базы данных используется режим открытия ios_base::app, позволяющий открыть файл для записи в конец файла, при этом, сохраняя ранее записанные данные), создание специализированного файла для регистрационных данных пользователя, и запись в него ФИО, аналогично создается специальный файл для хранения логина и пароля конкретного пользователя. Формирования уникальных файлов происходит по принципу сложения строк. Например, path=path+teature1.login+txt, где path-путь к директории, в которой хранятся файлы программы, teature1.login – уникальный логин пользователя, txt- строка, хранящая в себе “.txt”.

void Reg()
{
	std::string path = "C:\\journal\\regdata", datalog = "C:\\journal\\logdata.txt", txt = ".txt", user = "C:\\journal\\", delfile = "C:\\journal\\delfile.txt"; //объявление переменных типа string
	bool flag = 1; //объявление переменной типа bool
	DataofTeature teature1; //объявление переменной класса DataofTeature
	std::ofstream fout; //объявление переменной класса ofstream
	std::ifstream fin; //объявление переменной класса ifstream
	std::cout << "\t\t\tРегистрация:\n"; //ввод даных, необходимых для регистрации
	std::cout << "Введите фамилию: ";
	std::cin >> teature1.surname;
	std::cout << "Введите имя: ";
	std::cin >> teature1.name;
	std::cout << "Введите отчество: ";
	std::cin >> teature1.patronymic;
	std::cout << "Введите логин: ";
	std::cin >> teature1.login;
	while (flag)
	{
		bool flag2 = 0;
		fin.open(datalog);
		if (fin.is_open())
		{
			std::string data = "";
			while (!fin.eof())
			{
				std::getline(fin, data);
				if (teature1.login == data)		//проверка на существование данного логина в файле
				{
					flag2 = 1;
					flag = 1;
				}
			}
		}
		else
		{
			std::cout << "ERROR"; //Файл не удалось создать или открыть
		}
		if (flag2)
		{
			std::cout << "Данный логин уже существует, придумайте другой логин: "; //прозьба ввести логин повторно, если введенный до этого уже существует
			std::cin >> teature1.login;
			flag = 1;
		}
		else
		{
			flag = 0; //изменение булевой переменной для выхода из цыкла
		}
		fin.close();
	}
	path = path + teature1.login + txt; //формирование пути, для создания файла с ФИО аккаунта
	fout.open(path);
	if (fout.is_open())
	{
		fout << teature1.surname << "\n";
		fout << teature1.name << "\n";			//запись данных в файл
		fout << teature1.patronymic << "\n";
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fout.close();
	std::cout << "Введите пароль: ";
	std::cin >> teature1.password;		//ввод пароля
	fout.open(datalog, std::ios_base::app); //открыть файл для записи в конец файла
	if (fout.is_open())
	{
		fout << teature1.login << "\n"; //запись данных в файл
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fout.close();
	user = user + teature1.login + txt; //формирование пути хранения логина и пароля
	fout.open(user); //открытия файла
	if (fout.is_open())
	{
		fout << teature1.login << "\n";
		fout << teature1.password << "\n";		//запись данных в файл
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fout.close();
}

Authon

Функция Authon реализует авторизацию пользователя в программу.

В ходе выполнения функции, пользователю предлагается ввести логин и пароль. Следом идет проверка наличия логина в базе логинов, если логина в базе нет, пользователю
предлагается ввести логин повторно. Получив логин, программа открывает
специализированный файл пользователя, получая к нему путь, методом сложения
строк. В этом файле проверяется верность пароля, если пароль не совпадает, то
предлагается ввести пароль повторно. Как только все данные проверены, программа
открывает файл с ФИО пользователя и выводит на экран приветствие, используя ФИО
пользователя.

void Authon()
{
	std::string path = "C:\\journal\\regdata", datalog = "C:\\journal\\logdata.txt", txt = ".txt", user = "C:\\journal\\", delfile = "C:\\journal\\delfile.txt", login, password, filelog = ""; //объявление переменных типа string
	DataofTeature teature1; //объявление переменной класса DataofTeature
	std::ifstream fin; //объявление переменной класса ifstream
	bool flag = 1; //объявление переменной типа bool
	std::cout << "\t\t\tАвторизация:\n";
	std::cout << "Введите логин: ";
	std::cin >> login;			//ввод логина
	while (flag)
	{
		bool flag2 = 0;
		fin.open(datalog);		//проверка наличия логина в базе логинов
		if (fin.is_open())
		{
			while (!fin.eof())
			{
				std::getline(fin, filelog);
				if (login == filelog)
				{
					flag = 0;
					flag2 = 0;
					break;
				}
				else
				{
					flag2 = 1;
				}
			}
		}
		else
		{
			std::cout << "ERROR"; //Файл не удалось создать или открыть
		}
		if (flag2)
		{
			std::cout << "Такого логина не существует, введите логин повторно: \n";			//просьба ввести логин повторно
			std::cin >> login;
		}
		fin.close();
	}
	user = user + login + txt; //формирования пути нахождения файла с логинами и паролями
	flag = 1;
	std::cout << "Введите пароль: ";		//ввод пароля
	std::cin >> password;
	while (flag)
	{
		bool flag2 = 0;
		fin.open(user);
		if (fin.is_open())
		{
			while (!fin.eof())
			{
				std::getline(fin, filelog);
				if (password == filelog)
				{								//проверка верности пароля
					flag = 0;
					flag2 = 0;
					break;
				}
				else
				{
					flag2 = 1;
				}
			}
		}
		else
		{
			std::cout << "ERROR"; //Файл не удалось создать или открыть//
		}
		if (flag2)
		{
			std::cout << "Пароль введен не верно, попробуйте еще раз: \n";		//просьба ввести пароль повторно
			std::cin >> password;
		}
		fin.close();
	}
	std::cout << "Добро пожаловать ";
	path = path + login + txt;
	fin.open(path);
	if (fin.is_open())
	{
		std::string data = "";					//вывод приветствия на экран
		while (!fin.eof())
		{
			std::getline(fin, data);
			std::cout << data << " ";
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fin.close();
	std::cout << "\n";
}

GroupSelection

Функция реализует полноценный выбор группы в программе.

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

void GroupSelection()
{
	DataofStudent stud1; //объявление переменных класса DataofStudent
	std::string allgroup = "", path = "C:\\journal\\allgroup\\allgroup.txt", delfile = "C:\\journal\\allgroup\\delfile.txt", path2 = "C:\\journal\\allgroup\\", txt = ".txt", choice = ""; //объявление переменных типа string
	bool flag = 1; //объявление переменных типа bool
	std::ifstream fin; //объявление переменной класса ifstream
	std::ofstream fout; //объявление переменной класса ofstream
	std::cout << "Полный список групп: \n";
	fin.open(path);
	if (fin.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data);		//вывод а экран полного списка групп
			std::cout << "\t\t\t" << data << "\n";
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть//
	}
	fin.close();
	std::cout << "Введите название группы, которую хотите открыть: ";
	std::cin >> stud1.group;	//ввод название необходимой группы
	while (flag)
	{
		bool flag2 = 1;
		fin.open(path);
		if (fin.is_open())
		{
			std::string data = "";
			while (!fin.eof())
			{
				std::getline(fin, data);
				if (stud1.group == data)	//проверка на наличие введенной группы в списке групп
				{
					flag2 = 0;
					flag = 0;
				}
			}
		}
		else
		{
			std::cout << "ERROR"; //Файл не удалось создать или открыть
		}
		if (flag2)
		{
			std::cout << "Данной группы не существует, введите другую группу: ";
			std::cin >> stud1.group;	//просьба ввести название группы повторно
			flag = 1;
		}
		else
		{
			flag = 0;	//изменение буливой переменной для выхода из цыкла
		}
		fin.close();
	}
	nameofgroup = stud1.group; //присваивание названия группы в глобальную переменную
}

Grades

Функция Grades реализует, простановку оценок студентам.

В ходе выполнения функции, пользователю предлагается ввести дату, за которую он хочет выставить оценку. После получения программой даты, происходит проверка на существование файла с оценками на данную дату. Если файл существует, то происходит его запись в специализированный промежуточный файл, это происходит для реализации корректной и органичной записи в файл отметок, без потерь данных. Если файл не существует, то программа копирует данные из файла со списком группы в промежуточный файл. Следом, на экран выводится полный список группы с отметками (если они есть). Пользователю предлагается ввести фамилию и имя студента, которому он хочет выставить оценку. Как только программа получает эти данные, происходит проверка на наличие данного студента в группе, если его нет, то пользователю предлагается ввести фамилию и имя повторно. После получения данных программой, происходит создание файла для оценок на данную дату (принцип нахождения пути файла и формирования его название – сложение строк). Следом, идет поиск данного студента в промежуточном файле. Принцип поиска и записи таков: если фамилия и имя не совпадает с введенными пользователем, то происходит запись этих данных в файл с оценками, если ФИ совпали, то пользователю предлагается ввести студенту оценку, полученная строчка записывается в файл с оценками. В конце работы функции, на экран выводится список группы с внесенными изменениями.

void Grades()
{
	DataofStudent student1; //объявление переменных класса DataofStudent
	std::string way = "C:\\journal\\allgroup\\", delfile = "delfile.txt", txt = ".txt", attendance = "\\grade", choice = ""; //объявление переменных типа string
	bool flag = 0, flag2 = 1; //объявление переменных типа bool
	std::ofstream fout; //объявление переменной класса ofstream
	std::ifstream fin; //объявление переменной класса ifstream
	std::cout << "Введите дату за которую вы хотите проставить оценки: ";
	std::cin >> choice;	//ввод даты 
	fin.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open())
	{
		flag = 1;		//проверка наличия файла с оценками на данную дату
	}
	fin.close();
	if (flag)
	{
		fin.open(way + nameofgroup + attendance + choice + txt);
		fout.open(way + delfile);
		if (fin.is_open() and fout.is_open())
		{
			std::string data = "";
			while (!fin.eof())		//запись данных существующего файла в специализированный файл
			{
				std::getline(fin, data);
				fout << data << "\n";
			}
		}
		else
		{
			std::cout << "ERROR"; //Файл не удалось создать или открыть
		}
		fin.close();
		fout.close();
	}
	else
	{
		fin.open(way + nameofgroup + txt);
		fout.open(way + delfile);
		if (fin.is_open() and fout.is_open())
		{
			std::string data = "";
			while (!fin.eof())
			{									//запись  в специализированный файл списка группы 
				std::getline(fin, data);
				fout << data << "\n";
			}
		}
		else
		{
			std::cout << "ERROR"; //Файл не удалось создать или открыть
		}
		fin.close();
		fout.close();
	}
	fin.open(way + delfile);
	if (fin.is_open())
	{
		std::string data = "";
		while (!fin.eof())	//вывод списка группы на экран
		{
			std::getline(fin, data);
			std::cout << data << "\n";
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fin.close();
	std::cout << "Введите фамилию и имя студента. которому вы хотите выставить оценку: " << std::endl;
	std::cin >> student1.name;	//ввод фамили и имени студента
	while (flag2)
	{
		fin.open(way + delfile);
		if (fin.is_open())
		{
			std::string data = "";
			while (!fin.eof())
			{
				std::getline(fin, data);
				if (data == student1.name)
				{
					flag2 = 0;	//проверка наличия данно ФИ в списке группы
				}
			}
		}
		else
		{
			std::cout << "ERROR"; //Файл не удалось создать или открыть
		}
		if (flag2)
		{
			std::cout << "Такого студента не существует, повторите ввод фамилии и имени: "; //повторный ввод ФИ студента
			std::cin >> student1.name;
		}
		fin.close();
	}
	fin.open(way + delfile);
	fout.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open() and fout.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data);
			if (data == student1.name)
			{
				bool flag3 = 1;
				for (int i = 0; i < data.length(); i++)
				{											//процесс нахождения ФИ студента в файле
					if (flag3 and data[i] != '\t')
					{
						fout << data[i];	//запись данных в файл с оценками
					}
					else
					{
						flag3 = 0;
					}

				}
				std::string choice2;
				std::cout << "Введите оценку: ";	//ввод оценки
				std::cin >> choice2;
				fout << "\t" << choice2 << "\n";	//запись данных в файл с оценками
			}
			else
			{
				fout << data << "\n";	//запись данных в файл с оценками
			}
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fin.close();
	fout.close();
	std::cout << "\n";
	fin.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data);
			std::cout << "\t\t\t" << data << "\n";	//вывод измененных данных на экран
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fin.close();
}

Attendance

Функция Attendance реализует простановку посещаемости студентов с последующей записью в файл.

В ходе выполнения функции, пользователю предлагается ввести дату, за которую он хочет выставить посещаемость. После получения программой даты, происходит проверка на существование файла с посещаемостью на данную дату. Если файл существует, то происходит его запись в специализированный промежуточный файл, это происходит для реализации корректной и органичной записи в файл посещаемости, без потерь данных. Если файл не существует, то программа копирует данные из файла со списком группы в промежуточный файл. Следом, на экран выводится полный список группы с посещаемостью (если она есть). Пользователю предлагается ввести фамилию и имя студента, которому он хочет выставить посещаемость. Как только программа получает эти данные, происходит проверка на наличие данного студента в группе, если его нет, то пользователю предлагается ввести фамилию и имя повторно. После получения данных программой, происходит создание файла для посещаемости на данную дату (принцип нахождения пути файла и формирования его название – сложение строк). Следом, идет поиск данного студента в промежуточном файле. Принцип поиска и записи таков: если фамилия и имя не совпадает с введенными пользователем, то происходит запись этих данных в файл с оценками, если ФИ совпали, то пользователю предлагается ввести посещаемость студента, полученная строчка записывается в файл с посещаемостью. В конце работы функции, на экран выводится список группы с внесенными изменениями.

void Attendance()
{
	DataofStudent student1; //объявление переменной класса DataofStudent
	std::string way = "C:\\journal\\allgroup\\", delfile = "delfile.txt", txt = ".txt", attendance = "\\attendance", choice = "";//объявление переменных типа string
	bool flag = 0, flag2 = 1; //объявление переменной типа bool
	std::ofstream fout; //объявление пременной класса ofstream
	std::ifstream fin; //объявление переменной класса ifstream
	std::cout << "Введите дату за которую вы хотите проставить посещаемость: ";
	std::cin >> choice; //ввод даты
	fin.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open())
	{
		flag = 1;	//проверка на наличие файла
	}
	fin.close();
	if (flag)
	{
		fin.open(way + nameofgroup + attendance + choice + txt);
		fout.open(way + delfile);
		if (fin.is_open() and fout.is_open())
		{
			std::string data = "";
			while (!fin.eof())	//запись данных файла в промежуточный файл
			{
				std::getline(fin, data);
				fout << data << "\n";
			}
		}
		else
		{
			std::cout << "EROR";
		}
		fin.close();
		fout.close();
	}
	else
	{
		fin.open(way + nameofgroup + txt);
		fout.open(way + delfile);
		if (fin.is_open() and fout.is_open())
		{
			std::string data = "";
			while (!fin.eof())
			{						//запись списка группы в промежуточный файл
				std::getline(fin, data);
				fout << data << "\n";
			}
		}
		else
		{
			std::cout << "EROR";
		}
		fin.close();
		fout.close();
	}
	fin.open(way + delfile);
	if (fin.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data);
			std::cout << data << "\n";	//ввывод списка группы на экран
		}
	}
	else
	{
		std::cout << "EROR";
	}
	fin.close();
	std::cout << "Введите фамилию и имя студента. которому вы хотите выставить посещаемость: " << std::endl;
	std::cin >> student1.name;	//ввод фамили и имени студента
	while (flag2)
	{
		fin.open(way + delfile);
		if (fin.is_open())
		{
			std::string data = "";
			while (!fin.eof())
			{
				std::getline(fin, data);
				if (data == student1.name)	//проверка на наличие данного студента в группе
				{
					flag2 = 0;
				}
			}
		}
		else
		{
			std::cout << "EROR";
		}
		if (flag2)
		{
			std::cout << "Такого студента не существует, повторите ввод фамилии и имени: ";	//повторный ввод ФИ студента
			std::cin >> student1.name;
		}
		fin.close();
	}
	fin.open(way + delfile);
	fout.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open() and fout.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data);
			if (data == student1.name)
			{
				bool flag3 = 1;
				for (int i = 0; i < data.length(); i++)
				{
					if (flag3 and data[i] != '\t')
					{
						fout << data[i];	//процесс нахождения студента в файле
					}
					else
					{
						flag3 = 0;
					}

				}
				std::string choice2;
				std::cout << "Введите посещаемость: ";
				std::cin >> choice2; //ввод посещаемости
				fout << "\t" << choice2 << "\n";
			}
			else
			{
				fout << data << "\n";
			}
		}
	}
	else
	{
		std::cout << "EROR";
	}
	fin.close();
	fout.close();
	std::cout << "\n";
	fin.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data); //вывод измененных данных на экран
			std::cout << "\t\t\t" << data << "\n";
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fin.close();
}

Comment

Функция Comment реализует в программе написание комментария к дате.

В ходе выполнения функции, пользователю предлагается ввести дату, для которой он хочет написать комментарий. При получении программой даты, происходит открытие файла с режимом открытия ios_base::app (открыть файл для записи в конец файла). Наименование файла и путь его нахождения формируется, путем сложения строк. Пользователю предлагается ввести комментарий. Происходит запись данных в файл. После на экран выводятся изменённые данные файла.

void Comment()
{
	DataofStudent student1;//объявление переменной класса DataofStudent
	std::string way = "C:\\journal\\allgroup\\", delfile = "delfile.txt", txt = ".txt", attendance = "\\comment", choice = ""; //объявление переменнх типа string
	std::ofstream fout;//объявление переменной класса ofstream
	std::ifstream fin;//объявление переменной класса ifstream
	std::cout << "Введите дату для которой вы хотите оставить коментарий: ";
	std::cin >> choice; //ввод даты
	fout.open(way + nameofgroup + attendance + choice + txt, std::ios_base::app);
	if (fout.is_open())
	{
		std::string choice2;
		std::cout << "Введите коментарий: "; //ввод коментария
		std::cin >> choice2;
		fout << choice2 << "\n";
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	std::cout << "\n";
	fout.close();
	fin.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data);	//вывод изменненных данных на экран
			std::cout << "\t\t\t" << data << "\n";
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fin.close();

}

Deadline

Функция Deadline реализует в программе создание dedlin’а и комментария к нему, с записью этих данных в файл.

В ходе выполнения функции, пользователю предлагается ввести дату, на которую он хочет установить deadline. При получении программой даты, происходит открытие файла с режимом открытия ios_base::app (открыть файл для записи в конец файла). Наименование файла и путь его нахождения формируется, путем сложения строк. Пользователю предлагается ввести комментарий. Происходит запись данных в файл. После на экран выводятся изменённые данные файла.

void Deadline()
{
	DataofStudent student1; //объявление переменной класса DataofStudent
	std::string way = "C:\\journal\\allgroup\\", delfile = "delfile.txt", txt = ".txt", attendance = "\\deadline", choice = ""; //объявление переменной типа string
	std::ofstream fout; //объявление переменной класса ofstream
	std::ifstream fin; //объявление переменной класса ifstream
	std::cout << "Введите дату на которую вы хотите установить deadline: ";
	std::cin >> choice; //ввод даты
	fout.open(way + nameofgroup + attendance + choice + txt, std::ios_base::app);
	if (fout.is_open())
	{
		std::string choice2;
		std::cout << "Введите коментарий к deadlin'у: "; //ввод коментария 
		std::cin >> choice2;
		fout << choice2 << "\n";
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	std::cout << "\n";
	fout.close();
	fin.open(way + nameofgroup + attendance + choice + txt);
	if (fin.is_open())
	{
		std::string data = "";
		while (!fin.eof())
		{
			std::getline(fin, data);
			std::cout << "\t\t\t" << data << "\n"; //вывод измененных данных на экран
		}
	}
	else
	{
		std::cout << "ERROR"; //Файл не удалось создать или открыть
	}
	fin.close();
}

Main

Аналогично, основываясь на блок схеме, был написан код основной части программы.

В ходе выполнения программы, на экран выводится меню. Пользователю предлагается выбрать один из пунктов. При выборе пункта 1, вызывается функция Reg, а затем функция Authon; При выборе пункта 2, вызывается функция Authon; При выборе пункта 3 происходит выход из программы. После успешной авторизации вызывается функция GroupSelection. После выбора группы на экран выводится меню дальнейших действий. Пользователю предлагается выбрать один из пунктов. При выборе пункта 1 вызывается функция Grades; При выборе пункта 2 вызывается функция Attendance; При выборе пункта 3 вызывается функция Deadline; При выборе пункта 4 вызывается функция Comment; При выборе пункта 5 происходит выход из программы.

void main()
{
	std::string choice = ""; //объявление переменной типа string
	bool flag = 1; //объявление переменной типа bool
	setlocale(0, ""); //установка языкового стандарта для яязыка
	std::cout << "\t\t\tДобро пожаловать в электронный журнал\n"; //вывод меню на экран
	std::cout << "\t\t\tЕсли вы ходите зарегистрироваться введите 1\n\t\t\tЕсли выхотите авторизоваться введите 2\n\t\t\tЕсли вы хотите закрыть программу введите 3\n";
	std::cin >> choice;//ввод символа, отвечающего за выбор пункта меню
	if (choice == "3")
	{
		return; //выход из программы
	}
	while (flag)
	{
		if (choice == "1")
		{
			flag = 0;
			Reg(); //регистрация
			Authon();//авторизация
		}
		else
		{
			if (choice == "2" and flag)
			{
				Authon(); //авторизация
				flag = 0;
			}
			else
			{
				std::cout << "Сделайте выбор повторно: ";
				std::cin >> choice; //повторное осуществленеи выбора пункта меню
			}
		}
	}
	GroupSelection(); //выбор группы
	std::cout << "\n\t\t\tВыберете дальнейшее действие:\n"; //вывод меню выбора дальнейших действий
	std::cout << "\t\t\tЕсли вы хотите поставить оценку студенту, введите 1\n\t\t\tЕсли проставить посещаемость, введите 2\n\t\t\tЕсли вы хотите установить дату конца дедлайна, введите 3\n\t\t\tЕсли вы хотите написать коментарий, введите 4\n\t\t\tЕсли вы хотите закрыть программу введите 5\n";
	std::cin >> choice; // ввод символа, отвечающего за выбор пункта меню
	flag = 1;
	while (flag)
	{
		if (choice == "1")
		{
			flag = 0;
			Grades(); //простанока оценки
		}
		if (choice == "2")
		{
			flag = 0;
			Attendance(); //простановка посещаемости
		}
		if (choice == "3")
		{
			flag = 0;
			Deadline(); //установка deadlin'a
		}
		if (choice == "4")
		{
			flag = 0;
			Comment(); //написание комментария
		}
		if (choice == "5")
		{
			return; //выход из программы
		}
		if (choice != "1" and choice != "2" and choice != "3" and choice != "4" and choice != "5")
		{
			flag = 1;
			std::cout << "Повторите ввод: ";
			std::cin >> choice; //повторное осуществление выбора пункта меню
		}
	}
}

Для реализации полноценной работоспособности моей программы необходимо создать несколько текстовых файлов и директорий согласно диаграмме.

диаграмма
диаграмма

В файл allgroup.txt необходимо записать название группы. Также папке allgroup нужно создать папку с название группы и текстовый документ с названием группы, в который необходимо занести список группы.

Тестирование и отладка программы

Для проведения корректного и полного тестирования следует поставить несколько тест кейсов, а именно.

Тестирование работы регистрации
Тестирование работы регистрации
Тестирование авторизации
Тестирование авторизации
Тестирование выбора группы
Тестирование выбора группы
Тестирование постановки оценки
Тестирование постановки оценки
Тестирование постановки посещаемости
Тестирование постановки посещаемости
Тестирование установки даты конца дедлайна
Тестирование установки даты конца дедлайна
Тестирование написания комментария к дате
Тестирование написания комментария к дате

В ходе тестирования программы критических ошибок выявлено не было.

Заключение

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

  • Класс DataofTeature, хранящий в себе информацию о преподавателе.

  • Класс DataofStudent, хранящий в себе информацию о студенте.

  • Функция Reg, реализующая регистраци.

  • Функцию Authon, реализующая авторизацию в программу.

  • Функция GroupSelection, реализующая выбор группы.

  • Функция Grades, реализующая простановку оценок.

  • Функция Attendance, реализующая простановку посещаемости.

  • Функция Comment, отвечающая за возможность написания комментария к дате.

  • Функция Deadline, дающая возможность установить дэдлайн и написать к нему комментарий.

  • Функция main, в которой реализовано основное взаимодействие пользователя с программой (меню и т.д.).

Весь код программы был написан в среде разработки Visual Studio 2022. Суммарный объем строк в тексте программы составляет 724.




Комментарии (31):

  1. lair
    /#24761554 / +7

    А какова ценность этой публикации для читателей хабра (ну, кроме демонстрации нескольких хорошо известных ошибок)?

  2. hard2018
    /#24761612 / +7

    Ну всё, пиццот тыщ в час можно заколачивать

  3. Racheengel
    /#24761646 / +8

    Вот, примерно такие лабораторные у нас на 1 курсе были больше 20 лет назад...

    И то народ в основном GUI пытался прикручивать, или на борланде, или на дельфи.

    • Nick_Maverick
      /#24761874 / +4

      Ну я такое же писал на просто C лет 30 назад. А, и ещё переписал на паскаль, и с турбо вижн сделал gui. Это вроде курсач был, потому два языка. И да, все разделы на месте, даже заключение с тем на чем было писано, и строк сколько. Но сама идея публиковать нечто со структурой аналогичной курсачу это дааа. Антиплагиат передаст привет всем сдающим после этого нетленного произведения )

  4. nUser123
    /#24761654 / +7

    "Для реализации полноценной работоспособности моей программы необходимо создать несколько текстовых файлов и директорий согласно диаграмме" если это нужно делать вручную, то хотябы только поэтому уже нельзя назвать программу полноценной, если я верно вычитал смысл из заголовка. Ну и вообще с++ не учится за 3-4 месяца. Достаточно 21 день. Попробуйте перечитать вашу статью еще месяца через 3 или 4.

  5. MentalBlood
    /#24761680 / +9

    Рекомендую рассмотреть более аккуратное и развернутое именование сущностей как альтернативу комментариям


    P.S. Схемы это хорошо

  6. 0x6b657239
    /#24761714 / +3

    А полноценная программа - это какая? Вывод "Hello World!" - это полноценная программа или нет?

  7. JordanCpp
    /#24761850 / +3

    Где классы, тесты? Разбиение проекта на файлы? Или сейчас так уже не пишут?:)

  8. AlexeyALV
    /#24761962 / +4

    В первом алгоритме у вас два конца. Так не полагается делать.

    Ну и конечно делать из курсача статью на таком ресурсе - перебор.

  9. Kotofay
    /#24762510

    Кстати, классический UNIX-way.
    Составляем файл ответов и ./proga < answers.txt

  10. yamifa_1234
    /#24762544 / +2

    Совершенно не "юзерфрендли"... Представьте учителя что сидит и с командной строкой взаимодействует)

  11. 1Tiger1
    /#24762588 / +1

    Внимание! Количество условных конструкций, уровней вложенности и строк в методах многократно превысило допустимый предел. Срочно пройдите в ближайший биореактор на утилизацию!

  12. alex_ter
    /#24762882 / +1

    Пустил скупую слезу! А ведь не ведает молодежь своего счастья, что есть в C++ нормальные строки из коробки, воспринимает как данность )

  13. souls_arch
    /#24762894 / +2

    А зачем блок-схемы в разных масштабов? И главный алгоритм некорректно немного изображен. Радует, что есть молодежь, которая не лепит сразу что попало, а хотя бы думает. Разработка - это про думать, а не на клаве клацать.

  14. Kvason
    /#24762968 / -2

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

  15. azfrost
    /#24762970 / +9

    Бессмысленные комментарии типа "объявление переменной типа bool".

    Бессмысленные названия переменных.

    Неструктурированная логика, смешанная с данными, хтонические бойлерплейты непонятных условий.

    Спасибо, было больно.

  16. FirststepsRu
    /#24762972 / +10

    Интересно услышать комментарии Вашего препода, но ошибок и "то как делать не надо" много, поэтому хочется их просто перечислить, чтобы исправили.

    1. Зачем писать комментарии к переменным типа "переменная типа string" ? Это каким-то образом несет смысловую нагрузку ?!

    2. Именование переменных не очень. choice, choice2 и т.д. а по факту в первую попадает дата, во вторую комментарий. А почему не назвать input_date и input_comment ?

    3. Ввод от пользователя никак не обрабатывается, к примеру сразу на основе choice создается путь до файла. А что если туда ввести "..\\..\\Users\\..." можно прочитать/затереть какие-нибудь файлы пользователя ?!

    4. fin.close() надо делать в блоке if (fin.is_open()) когда файл реально открыт, а иначе он и не открыт вовсе.

    5. Зачем сделана куча if (choice == "X"){ ... }. Вас не учили switch/case ?

    6. Если используете bool, то уже и пишите true/false а не 0/1 иначе для чего ?

    7. Во всем мире путь до файла называется path, а у вас way :)

    8. Класс без методов это struct, или это задел на будущее ?

    9. Длинные строки вырывают глаза (все переменные std::string для пути к файлу уехали за скрол). У меня на работе так быдлокодят, задолбали oneliner'ы на килобайт, поубивал бы.

    • hard2018
      /#24764034

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

    • drafterleo
      /#24764076

      5. Зачем сделана куча if (choice == "X"){ ... }. Вас не учили switch/case ?

      Разве C++ позволяет строки в switch/case? Насколько помню, там только целые и enum-ы можно.

      • FirststepsRu
        /#24764200

        Никто не мешает распарсить string в int, заодно проверить корректность ввода пользователя.

        Либо на крайний случай делать так:

        if (choice == "1") {
        // case 1
        } else if (choice == "2") {
        // case 2
        } else if (...) {
        //....
        } else {
        // default
        }

        Иначе в текущем варианте каждый раз придется разращивать if, который должен отрабатывать смысл default

  17. saboteur_kiev
    /#24763070 / +3

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

    • Racheengel
      /#24763418 / +1

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

      • iig
        /#24764374

        Еще лучше разделить администрирование системы и использование.

  18. iig
    /#24764372

    НЯП, в начале работы нужно ввести ФИО (зачем??), логин и пароль. Если же пароль неизвестен - можно посмотреть в файле, правда же?

    Можно делать программы с GUI. Можно делать многопользовательские системы. Можно использовать готовые базы данных. А то, что у вас получилось - это что-то в стиле 70-х, но на С++.

  19. VXP
    /#24764684 / +3

    Муд: 1-й курс любой специальности с программированием, курсовая

  20. MegaMANGO
    /#24765366 / +3

    Люди в комментариях больно много душнят. Я понимаю, что вы все опытные программисты и всё такое, но чувак сам пишет, что программирует 3-4 месяца и попробовал написать что-то довольно большое впервые, поэтому относиться к его посту с полной серьёзностью, мол "а я вот могу написать программу получше, с тестами и классами" – это просто смешно.) Как-будто вы в своё первое полугодие программирование уже идеально знали большинство его составляющих и паттернов

    • lair
      /#24765536 / +5

      Скажем так, я в свое первое полугодие не выкладывал свои творения на Хабр.


      Зачем это здесь?

    • ALexhha
      /#24767272

      но чувак сам пишет, что программирует 3-4 месяца и попробовал написать что-то довольно большое впервые,

      а зачем тогда выкладывать это на хабр ? Чтобы что ?

      А то получается из серии - посмотрите как я провел лето

      • iig
        /#24767356

        Первый блин всегда comом. Было бы интересно, кстати, посмотреть вторую статью от автора через полгода.

  21. lovermann
    /#24765954

    Ну, если уж, тогда для досовского интерфейса лучше использовать такое:
    1. Поставить оценку
    2. Авторизироваться
    3. Выйти из программы.

    ... ,
    а не "Если вы хотите ...".

    Такая форма "общения" намного короче и понятнее бóльшему числу пользователей, потому что они наверняка пользовались USSD при общении с мобильным оператором.

    • iig
      /#24766164 / +1

      Во времена ДОС программисты уже умели рисовать меню с помощью ASCII символов.