
БЕЛОРУССКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
ИНФОРМАТИКИ И РАДИОЭЛЕКТРОНИКИ
Кафедра программного обеспечения информационных технологий
Факультет ФКСиС
Специальность ПОИТ
Контрольная работа №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;
}