Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсач.docx
Скачиваний:
0
Добавлен:
06.06.2025
Размер:
556.29 Кб
Скачать

Описание переменных:

Функция

Имя

Тип

Назначение

int main()

choice

int

Выбор действия в меню

num_records

int

Количество структур в массиве

text

char

Меню

records

struct*

Массив структур

buffer

char

Содержание файла

file

FILE*

Файл с исходными данными

i

int

Итератор цикла

void add_record()

new_record

struct

Новая структура

void delete_record()

id

int

Значения поля структуры для удаления

tempFile

FILE*

Новый файл для копирования из исходного

tempRecord

struct

Новая структура для копирования исходных

void alter_record()

id

int

Значение поля структуры для изменения

new_record

struct

Новая структура

tempFile

FILE*

Новый файл для копирования из исходного

tempRecord

struct

Новая структура для копирования исходных

void search()

param

int

Выбор поля для поиска

void search_by_id

param

int

Значение поля для поиска

void search_by_name

param

char

Значение поля для поиска

void search_by_price

param

double

Значение поля для поиска

void search_by_quantity

param

int

Значение поля для поиска

void search_by_weight

param

double

Значение поля для поиска

void id_comparator

l

int

Значение поля для сравнивания

r

int

Значение поля для сравнивания

void quantity_comparator

l

int

Значение поля для сравнивания

r

int

Значение поля для сравнивания

void sort()

param

int

Выбор поля для сортировки

Схема алгоритма:

Функция main():

Функция print_info():

Функция add_record():

Функция alter_record():

Функция delete_record():

Функция print_all_records():

Функция search():

Функция search_by_id():

Функция search_by_name():

Функция search_by_price():

Функция search_by_quantity():

Функция search_by_weight():

Функция sort():

Общая схема программы

Контрольные примеры

Исходные данные

Результат

1 Banana 20.0 10 0.15

2 Chocolade 30.0 20 0.1

3 Milk 40.0 30 1

4 Eggs 50.0 40 0.225

5 Chips 60.0 50 0.3

3 1

1 Chocolade 30.0 20 0.1

2 Milk 40.0 30 1

3 Eggs 50.0 40 0.225

4 Chips 60.0 50 0.3

1 Banana 20.0 10 0.15

2 Chocolade 30.0 20 0.1

3 Milk 40.0 30 1

4 Eggs 50.0 40 0.225

5 Chips 60.0 50 0.3

1 6 Beer 70.0 340 0.5

Новая запись добавится в массив структур

Текст программы

#define _CRT_SECURE_NO_WARNINGS

// вывод, работа со строками, работа с памятью

#include <stdio.h>

#include <string.h>

#include <stdlib.h>

typedef struct Product

{

int id;

char name[20];

double price;

int quantity;

double weight;

} Product;

Описание структуры

// Вывести один продукт

void print_record(Product record)

{

printf("%d. Name: %s, Price: %.2f, Quantity: %d, Weight: %.2f\n", record.id, record.name, record.price, record.quantity, record.weight);

}

// Вывести все продукты

void print_all_records(Product* records, int size)

{

for (int i = 0; i < size; ++i)

print_record(records[i]);

}

// Вывести информацию о программе

void print_info()

{

printf("This program is database that stores different products.\n");

}

Функции для вывода

void add_record(Product** records, int size)

{

// Открываем файл

FILE* file = fopen("records.txt", "a+");

// Читаем с клавиатуры новый продукт

Product new_record;

printf("Enter id, name, price, quantity, weight (space delimited): ");

scanf("%d %s %lf %d %lf", &new_record.id, new_record.name, &new_record.price, &new_record.quantity, &new_record.weight);

// Выделяем ещё одну ячейку памяти типа Product, чтобы записать туда новый элемент

*records = (Product*)realloc(*records, (size + 1) * sizeof(Product));

(*records)[size] = new_record;

// Пишем новый продукт в файл

fprintf(file, "\n%d,%s,%lf,%d,%lf", new_record.id, new_record.name, new_record.price, new_record.quantity, new_record.weight);

fclose(file);

}

// Удалить запись

void delete_record(Product** records, int size)

{

// Вводим id записи, которую хотим удалить

int id = -1;

printf("Enter id of the record u want to delete: ");

scanf("%d", &id);

// Удаляем запись из массива

for (int i = 0; i < size; i++)

if ((*records)[i].id == id)

{

for (int j = i; j < size - 1; j++)

(*records)[j] = (*records)[j + 1];

break;

}

// Реаллоцируем память на 1 элемент меньше, т.к. только что удалили элемент

*records = (Product*)realloc(*records, (size - 1) * sizeof(Product));

// Удаляем запись из файла

FILE* file = fopen("records.txt", "r");

FILE* tempFile = fopen("temp.txt", "w");

// Читаем записи в tempRecord, если id не равен искомому, записываем во временный файл, если равен - не делаем ничего

Product tempRecord;

while (fscanf(file, "%d,%[^,],%lf,%d,%lf", &tempRecord.id, tempRecord.name, &tempRecord.price, &tempRecord.quantity, &tempRecord.weight) != EOF) {

if (tempRecord.id != id) {

fprintf(tempFile, "%d,%s,%lf,%d,%lf\n", tempRecord.id, tempRecord.name, tempRecord.price, tempRecord.quantity, tempRecord.weight);

}

}

fclose(file);

fclose(tempFile);

// Удаляем старый файл, переименовываем новый

remove("records.txt");

rename("temp.txt", "records.txt");

}

// Изменить запись

void alter_record(Product** records, int size)

{

// Считываем айди записи, которую надо обновить, а также считываем новую запись, которую запишем на место старой

int id = -1;

printf("Enter id of the record u want to alter: ");

scanf("%d", &id);

Product new_record;

printf("Enter id, name, price, quantity, weight (space delimited): ");

scanf("%d %s %lf %d %lf", &new_record.id, new_record.name, &new_record.price, &new_record.quantity, &new_record.weight);

// Переписываем старую запись при совпадении id

for (int i = 0; i < size; ++i)

if ((*records)[i].id == id)

(*records)[i] = new_record;

// Используем киллерфичу из прошлой функции с двумя файлами

FILE* file = fopen("records.txt", "r");

FILE* tempFile = fopen("temp.txt", "w");

Product tempRecord;

while (fscanf(file, "%d,%[^,],%lf,%d,%lf", &tempRecord.id, tempRecord.name, &tempRecord.price, &tempRecord.quantity, &tempRecord.weight) != EOF) {

// Если id не совпали, просто записываем строку из старого файла

if (tempRecord.id != id) {

fprintf(tempFile, "%d,%s,%lf,%d,%lf\n", tempRecord.id, tempRecord.name, tempRecord.price, tempRecord.quantity, tempRecord.weight);

}

else

// Если совпали, записываем не строку из старого файла, а поля new_record, которые считали с клавиатуры

fprintf(tempFile, "%d,%s,%lf,%d,%lf\n", new_record.id, new_record.name, new_record.price, new_record.quantity, new_record.weight);

}

fclose(file);

fclose(tempFile);

remove("records.txt");

rename("temp.txt", "records.txt");

}

Функции для редактирования записей

// НАЧАЛО ФУНКЦИЙ ДЛЯ ПОИСКА (они все однотипные, перебор и вывод)

void search_by_id(Product* records, int size)

{

int param;

printf("Enter id: ");

scanf("%d", &param);

printf("Found such records:\n");

for (int i = 0; i < size; ++i)

{

if (records[i].id == param)

print_record(records[i]);

}

}

void search_by_name(Product* records, int size)

{

char name[20];

printf("Enter name: ");

fscanf(stdin, "%s", name);

printf("Found such records:\n");

for (int i = 0; i < size; ++i)

{

if (strcmp(records[i].name, name) == 0)

print_record(records[i]);

}

}

void search_by_price(Product* records, int size)

{

double param;

printf("Enter price: ");

scanf("%lf", &param);

printf("Found such records:\n");

for (int i = 0; i < size; ++i)

{

if (records[i].price == param)

print_record(records[i]);

}

}

void search_by_quantity(Product* records, int size)

{

int param;

printf("Enter quantity: ");

scanf("%d", &param);

printf("Found such records:\n");

for (int i = 0; i < size; ++i)

{

if (records[i].quantity == param)

print_record(records[i]);

}

}

void search_by_weight(Product* records, int size)

{

double param;

printf("Enter weight: ");

scanf("%lf", &param);

printf("Found such records:\n");

for (int i = 0; i < size; ++i)

{

if (records[i].weight == param)

print_record(records[i]);

}

}

// КОНЕЦ ФУНКЦИЙ ДЛЯ ПОИСКА

// Функция поиска, которую вызываем из меню

void search(Product* records, int size)

{

// Даём пользователю выбор, по какому полю искать

int param = -1;

printf("1. Search by id\n2. Search by name\n3. Search by price\n4. Search by quantity\n5. Search by weight\n");

printf("Enter the parameter to search by: ");

scanf("%d", &param);

// В зависимости от выбора, вызываем функцию для поиска

switch (param)

{

case 1:

search_by_id(records, size);

break;

case 2:

search_by_name(records, size);

break;

case 3:

search_by_price(records, size);

break;

case 4:

search_by_quantity(records, size);

break;

case 5:

search_by_weight(records, size);

break;

default:

printf("Wrong input\n");

break;

}

}

Функции для поиска

// Функция для передачи в qsort, сравнивает две записи по id

int id_comparator(const void* p, const void* q)

{

int l = ((struct Product*)p)->id;

int r = ((struct Product*)q)->id;

return (l - r);

}

// Функция для передачи в qsort, сравнивает две записи по кол-ву

int quantity_comparator(const void* p, const void* q)

{

int l = ((struct Product*)p)->quantity;

int r = ((struct Product*)q)->quantity;

return (l - r);

}

// Функция сортировки, которую вызываем из меню

void sort(Product** records, int size)

{

// Даём пользователю выбор, по какому полю сортировать

int param = -1;

printf("1. Sort by id\n2. Sort by quantity\n");

printf("Enter the parameter to search by: ");

scanf("%d", &param);

// В зависимости от выбора пользователя, сортируем массив, передавая в qsort функцию для сравнения двух записей

switch (param)

{

case 1:

qsort(*records, size, sizeof(Product), id_comparator);

break;

case 2:

qsort(*records, size, sizeof(Product), quantity_comparator);

break;

default:

printf("wrong input");

break;

}

// Пишем в файл отсортированный массив

FILE* file = fopen("records.txt", "w");

for (int i = 0; i < size; ++i)

{

fprintf(file, "%d,%s,%lf,%d,%lf\n", (*records)[i].id, (*records)[i].name, (*records)[i].price, (*records)[i].quantity, (*records)[i].weight);

}

fclose(file);

}

Функции для сортировки

int main()

{

// Текст для вывода

char* text = "0.Info \n1.Add record \n2.Alter record \n3.Delete record \n4.Print records \n5.Search by.. \n6.Sort by.. \n7.Exit";

// Открываем файл

FILE* file = fopen("records.txt", "r");

if (file == NULL)

{

printf("Error opening file ");

return 1;

}

// Считаем кол-во записей

int num_records = 0;

while (!feof(file))

{

char buffer[256];

if (fgets(buffer, 256, file) != NULL) {

num_records++;

}

}

rewind(file);

// Создаём массив

Product* records = (Product*)malloc(num_records * sizeof(Product));

// Читаем записи из файла в массив

for (int i = 0; i < num_records; ++i)

fscanf(file, "%d,%[^,],%lf,%d,%lf", &records[i].id, records[i].name, &records[i].price, &records[i].quantity, &records[i].weight);

fclose(file);

Создание массива и чтение записей из файла

// Главный цикл

while (1)

{

// Вводим выбор

int choice = -1;

printf("%s\n", text);

printf("Enter the command: ");

scanf("%d", &choice);

// Обрабатываем выбор

switch (choice)

{

case 0:

print_info();

break;

case 1:

add_record(&records, num_records);

++num_records;

break;

case 2:

alter_record(&records, num_records);

break;

case 3:

delete_record(&records, num_records);

--num_records;

break;

case 4:

print_all_records(records, num_records);

break;

case 5:

search(records, num_records);

break;

case 6:

sort(&records, num_records);

break;

case 7:

free(records);

return 0;

break;

default:

printf("Wrong input");

break;

}

system("pause");

system("cls");

}

}

Главный цикл программы


Примеры работы программы

Заключение

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

В процессе реализации программы были использованы функции:

Из stdio.h: printf , fgets.

Из stdlib.h: malloc, realloc, free.

Из string.h: strcmp