Добавил:
БГУИР ПОИТ Дистанционное Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Часть 2 / КР2_В5 / КР2.docx
Скачиваний:
14
Добавлен:
31.01.2022
Размер:
82.74 Кб
Скачать

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

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

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

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

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

Контрольная работа №2

по дисциплине «Языки программирования. Часть 2»

Вариант 5

Выполнил студент: Бордон Е.С.

группа 991051

Зачетная книжка № 99105004

Минск 2021

Задание:

5. Разработать программу формирования файла, содержащего сведения

о студентах. Каждый элемент этого файла должен содержать следующие

данные: номер группы; фамилию; год рождения; средний балл за

последнюю сессию. Предусмотреть возможность добавления, удаления и

корректировки записей.

Пояснения к работе программы:

Программа реализована на языке программирования Си в программной среде разработки Visual Studio 2019. Программы выполнена в консольном режиме.

Программа была создана на базе контрольной работы 1.

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

struct student // структура для записи студента

{

int group;

char name[30];

float ball;

int year;

};

struct student* person; // массив студентов

int autovvod() {

FILE* file;

fopen_s(&file, "test.txt", "r");

int count = 0;

if (file != 0) {

while (fscanf_s(file, "%*[^\n]%*c") != EOF)

count++;

count = (count) / 4; // считаем колличесво строчек и число записей в файле

if (ferror(file))

count = 0;

}

fseek(file, 0L, SEEK_SET); /* Перейти в начало файла */

if (count != 0) { // Заполняем массив

person = (struct student*)malloc(count * sizeof(struct student));

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);

fscanf_s(file, "%d", &person[i].year);

}

}

}

if (file != 0) { // закрываем файл

fclose(file);

}

return count; // возвращаем число записей!

}

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

FILE* file;

fopen_s(&file, "test.txt", "w");

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

fprintf(file, "%d\n", person[i].group);

fprintf(file, "%s\n", person[i].name);

fprintf(file, "%f\n", person[i].ball);

fprintf(file, "%d\n", person[i].year);

}

if (file != 0) { // закрываем файл

fclose(file);

}

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

void vvod(int n, int n_p) {

printf("\n");

for (int i = n; i < n_p; 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);

do {

printf("Введите год рождения студента: ");

fseek(stdin, 0, SEEK_END); // очистка потока

} while (scanf_s("%d", &person[i].year) != 1);

}

printf("\n");

}

Удаление записи происходит с перестановкой последующих элементов на позицию вверх и последующем уменьшение динамического массива на единицу:

for (int i = (ch - 1); i < (count - 1); i++) {

person[i] = person[i + 1];

}

count--; // уменьшаем число записей на 1

person = (struct student*)realloc(person, count * sizeof(struct student));

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

Файл test.txt находится в коневой папке с исходными файлами

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

Результат работы программы:

Рис. 1 меню

Рис. 1 добавление элемента

Листинг программы: файл “functions.h”:

#pragma once

struct student // структура для записи студента

{

Int group;

char name[30];

float ball;

Int year;

};

struct student* person; // массив студентов

// меню

void menu() {

printf("1. Добавить записи о студентах:\n");

printf("2. Редактировать запись о студенте:\n");

printf("3. Удалить запись о студенте:\n");

printf("4. Отсортировать студентов по группам, разместив фамилии студентов в группе по среднему баллу:\n");

printf("5. Сохранить данные в файл\n");

printf("6. Выход\n");

}

// функция ввода данных

void vvod(int n, int n_p) {

printf("\n");

for (int i = n; i < n_p; 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);

do {

printf("Введите год рождения студента: ");

fseek(stdin, 0, SEEK_END); // очистка потока

} while (scanf_s("%d", &person[i].year) != 1);

}

printf("\n");

}

Int autovvod() {

FILE* file;

fopen_s(&file, "test.txt", "r");

int count = 0;

if (file != 0) {

while (fscanf_s(file, "%*[^\n]%*c") != EOF)

count++;

count = (count) / 4; // считаем колличесво строчек и число записей в файле

If (ferror(file))

count = 0;

}

fseek(file, 0L, SEEK_SET); /* Перейти в начало файла */

if (count != 0) { // Заполняем массив

person = (struct student*)malloc(count * sizeof(struct student));

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);

fscanf_s(file, "%d", &person[i].year);

}

}

}

if (file != 0) { // закрываем файл

fclose(file);

}

return count; // возвращаем число записей!

}

void print(int count) {

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

printf("| Всего студентов: %2d |\n", count);

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

printf("| № | Группа | Фамилия | С/Б | Год рождения |\n");

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

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

printf("| %2d | %2d | %15s | %3.2f | %4d |\n", (i + 1), person[i].group, person[i].name, person[i].ball, person[i].year);

}

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;

}

}

}

}

}

void save_f(int count) {

FILE* file;

fopen_s(&file, "test.txt", "w");

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

fprintf(file, "%d\n", person[i].group);

fprintf(file, "%s\n", person[i].name);

fprintf(file, "%f\n", person[i].ball);

fprintf(file, "%d\n", person[i].year);

}

if (file != 0) { // закрываем файл

fclose(file);

}

}

Листинг программы: файл “project.c ”:

#include <stdio.h>

#include <stdlib.h>

#include <locale.h> // для RU

#include "functions.h"

int main() {

setlocale(LC_ALL, "Rus"); // для RU

int count = autovvod(); // колличесво записей

int choice = 0; // меню

while (choice != 6) { //Выход 6

print(count); // Выводим спискок на экран

menu(); // выводим меню управления

// проверка ввода пунктов меню

do {

printf("\nВведи число: ");

fseek(stdin, 0, SEEK_END); // очистка потока

} while (scanf_s("%d", &choice) != 1);

switch (choice)

{

case 1: printf("\n"); // добавить

printf("Сколько всего записей будет?\n");

int count_plus;

do {

printf("\nВведи число количества записей: ");

fseek(stdin, 0, SEEK_END); // очистка потока

} while (scanf_s("%d", &count_plus) != 1 || count_plus <= 0);

if (count != 0)

person = (struct student*)realloc(person, (count + count_plus) * sizeof(struct student)); // Увеличение массива на count_plus

else person = (struct student*)malloc(count_plus * sizeof(struct student)); // Если до этого нет данных

vvod(count, (count + count_plus)); // функция ввода данных в массив

count += count_plus; // переопределяем число записей

break;

case 2: // редактировать запись о студенте

if (count > 0) {

int ch;

do {

printf("\nВведите номер записи которую нужно отредактировать: ");

fseek(stdin, 0, SEEK_END); // очистка потока

} while (scanf_s("%d", &ch) != 1 || ch <= 0 || ch > count);

vvod((ch - 1), ch);

}

else

{

printf("Списки пусты!\n");

printf("\n");

}

break;

case 3: // Удалить запись о студенте

if (count > 0) {

int ch;

struct student ss;

do {

printf("\nВведите номер записи которую нужно удалить: ");

fseek(stdin, 0, SEEK_END); // очистка потока

} while (scanf_s("%d", &ch) != 1 || ch <= 0 || ch > count);

for (int i = (ch - 1); i < (count - 1); i++) {

person[i] = person[i + 1];

}

count--; // уменьшаем число записей на 1

person = (struct student*)realloc(person, count * sizeof(struct student)); // уменьшаем массив на 1

}

else

{

printf("Списки пусты!\n");

printf("\n");

}

break;

case 4: printf("\n"); // сортировка массива по КР1

if (count > 0) {

sortarr(count);

printf("Структура списка отсортирована!\n");

printf("\n");

}

else

{

printf("Списки пусты!\n");

printf("\n");

}

break;

case 5: printf("\n"); // сохранить данные в файл!

if (count > 0) {

save_f(count);

printf("Файл сохранен!\n");

printf("\n");

}

else

{

printf("Нет данных для сохранения!\n");

printf("\n");

}

break;

case 6: printf("\n"); // выход

break;

default: printf("Неизвестная команда!\n");

break;

}

}

free(person); // освобождаем память

system("pause");

return 0;

}