БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Кафедра программного обеспечения информационных технологий
Факультет ФКСиС
Специальность ПОИТ
Контрольная работа №1
по дисциплине «Языки программирования. Часть 2»
Вариант 5
Выполнил студент: Бордон Е.С.
группа 991051
Зачетная книжка № 99105004
Минск 2021
Задание:
5. Написать программу формирования ведомости об успеваемости
студентов. Каждая запись этой ведомости должна содержать номер группы,
фамилию студента, средний балл за последнюю сессию. Необходимо
распечатать списки по группам. В каждой группе фамилии студентов
разместить в порядке убывания среднего балла.
Пояснения к работе программы:
Программа реализована на языке программирования Си в программной среде разработки Visual Studio 2019. Программы выполнена в консольном режиме.
В качестве пунктов меню были использованы кнопки: добавить, распечатать и отсортировать. Для тестирования программы была добавлена кнопка загрузки данных из заранее подготовленного текстового файла test.txt.
void menu() {
printf("1. Добавить записи о студентах:\n");
printf("2. Распечатать списки студентов:\n");
printf("3. Отсортировать студентов по группам, разместив фамилии студентов в группе по среднему баллу:\n");
printf("4. Выход\n");
printf("777. ->загрузить данные о студентах из готового файла test.txt для быстрой проверки работы программы\n");
}
Управление меню реализовано через цикл while с выходом из программы через «кнопку 4». Выбор пункта меню реализован через оператор switch case. Для проверки корректности ввода пользователем данных добавлена проверка с циклом постусловием (тк оператор scanf возвращает число корректно введенных данных).
do {
printf("\nВведи число: ");
fseek(stdin, 0, SEEK_END); // очистка потока
}
while (scanf_s("%d", &choice) != 1);
Далее в программе весь ввод будет проверяться с помощью этой функции.
Структура данных имеет вид:
struct student // структура для записи студента
{
int group;
char name[30];
float ball;
};
Тк мы не знаем сколько будет записей был организован одномерный динамический массив:
struct student *person; // массив студентов
person = (struct student*)malloc(count * sizeof(struct student));
int count = 0; // колличесво записей
Функция ввода данных была организована через цикл со счетчиком с передачей параметра количества записей.
void vvod(int n) {
printf("\n");
for (int i = 0; i < n; i++) {
// делаем проверку на правильность ввода
do {
printf("Введите номер группы: ");
fseek(stdin, 0, SEEK_END); // очистка потока
} while (scanf_s("%d", &person[i].group) != 1);
// тк тут массив char проверка не нужна
printf("Введите фамилию студента: ");
scanf_s("%s", &person[i].name, sizeof(person[i].name));
do {
printf("Введите средний балл: ");
fseek(stdin, 0, SEEK_END); // очистка потока
} while (scanf_s("%f", &person[i].ball) != 1);
}
printf("\n");
}
Функция сортировки выполнена методом «пузырька». Массив сортируется по группам и внутри группы по среднему баллу ученика:
void sortarr(int count) {
struct student ss;
for (int i = 1; i < count; i++) {
for (int j = 0; j < (count - i); j++) {
if (person[j].group > person[j + 1].group) {
ss = person[j];
person[j] = person[j + 1];
person[j + 1] = ss;
}
if (person[j].group == person[j + 1].group) {
if (person[j].ball < person[j + 1].ball) {
ss = person[j];
person[j] = person[j + 1];
person[j + 1] = ss;
}
}
}
}
}
Функция вывода также выполнена через цикл со счетчиком.
Все функции программы вынесены в отдельный заголовочный файл.
Файл test.txt находится в коневой папке с исходными файлами
В ходе тестирования программы ошибок не обнаружено.
Результат работы программы:
Рис. 1 меню
Рис. 2 список до сортировки
Рис. 3 список после сортировки
Листинг программы: файл “functions.h”:
#pragma once
struct student // структура для записи студента
{
int group;
char name[30];
float ball;
};
struct student *person; // массив студентов
// меню
void menu() {
printf("1. Добавить записи о студентах:\n");
printf("2. Распечатать списки студентов:\n");
printf("3. Отсортировать студентов по группам, разместив фамилии студентов в группе по среднему баллу:\n");
printf("4. Выход\n");
printf("777. ->загрузить данные о студентах из готового файла test.txt для быстрой проверки работы программы\n");
}
// функция ввода данных
void vvod(int n) {
printf("\n");
for (int i = 0; i < n; i++) {
// делаем проверку на правильность ввода
do {
printf("Введите номер группы: ");
fseek(stdin, 0, SEEK_END); // очистка потока
} while (scanf_s("%d", &person[i].group) != 1);
// тк тут массив char проверка не нужна
printf("Введите фамилию студента: ");
scanf_s("%s", &person[i].name, sizeof(person[i].name));
do {
printf("Введите средний балл: ");
fseek(stdin, 0, SEEK_END); // очистка потока
} while (scanf_s("%f", &person[i].ball) != 1);
}
printf("\n");
}
void autovvod(int count) {
free(person); // если повторный ввод
person = (struct student*)malloc(count * sizeof(struct student));
FILE* file;
fopen_s(&file, "test.txt", "r");
for (int i = 0; i < count; i++) {
if (file != 0) {
fscanf_s(file, "%d", &person[i].group);
fscanf_s(file, "%s", &person[i].name, sizeof(person[i].name));
fscanf_s(file, "%f", &person[i].ball);
}
}
if (file != 0) {
fclose(file);
}
}
void print(int count) {
printf("|-------------------------------------------------------|\n");
printf("| Всего студентов: %d |\n", count);
printf("|-------------------------------------------------------|\n");
printf("| № | Фамилия | С_Б |\n");
printf("|-------------------------------------------------------|\n");
for (int i = 0; i < count; i++) {
printf("| %2d | %15s | %3.2f |\n", person[i].group, person[i].name, person[i].ball);
}
printf("|-------------------------------------------------------|\n");
printf("\n");
}
// сортировка
void sortarr(int count) {
struct student ss;
for (int i = 1; i < count; i++) {
for (int j = 0; j < (count - i); j++) {
if (person[j].group > person[j + 1].group) {
ss = person[j];
person[j] = person[j + 1];
person[j + 1] = ss;
}
if (person[j].group == person[j + 1].group) {
if (person[j].ball < person[j + 1].ball) {
ss = person[j];
person[j] = person[j + 1];
person[j + 1] = ss;
}
}
}
}
}
Листинг программы: файл “progect.c”:
#include <stdio.h>
#include <stdlib.h>
#include <locale.h> // для RU
#include "functions.h"
int main() {
setlocale(LC_ALL, "Rus"); // для RU
int count = 0; // колличесво записей
int choice = 0; // меню
while (choice != 4) {
menu();
// проверка ввода
do {
printf("\nВведи число: ");
fseek(stdin, 0, SEEK_END); // очистка потока
}
while (scanf_s("%d", &choice) != 1);
switch (choice)
{
case 1: printf("\n"); // добавить
printf("Сколько всего записей будет?\n");
do {
printf("\nВведи число количества записей: ");
fseek(stdin, 0, SEEK_END); // очистка потока
} while (scanf_s("%d", &count) != 1 || count == 0);
free(person);// если повторный ввод
person = (struct student*)malloc(count * sizeof(struct student));
vvod(count); // функция ввода данных
break;
case 2: printf("\n");// распечатать списки студентов
if (count > 0) {
print(count);
}
else
{
printf("Списки пусты!\n");
printf("\n");
}
break;
case 777:
count = 15;
autovvod(count); // в тестовом файле всего 45ст по 3 записи =15
printf("Данные заполнены!\n");
printf("\n");
break;
case 3: printf("\n");
if (count > 0) {
sortarr(count);
printf("Структура списка отсортирована!\n");
printf("\n");
}
else
{
printf("Списки пусты!\n");
printf("\n");
}
break;
case 4: printf("\n"); // выход
break;
default: printf("Неизвестная команда!\n");
break;
}
}
system("pause");
return 0;
}