Добавил:
БГУИР ПОИТ Дистанционное Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Часть 2 / КР1_В5 / КР1

.docx
Скачиваний:
11
Добавлен:
31.01.2022
Размер:
64.09 Кб
Скачать

БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ

ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ

Кафедра программного обеспечения информационных технологий

Факультет ФКСиС

Специальность ПОИТ

Контрольная работа №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;

}