
Описание переменных:
-
Функция
Имя
Тип
Назначение
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", ¶m);
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", ¶m);
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", ¶m);
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", ¶m);
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", ¶m);
// В зависимости от выбора, вызываем функцию для поиска 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", ¶m);
// В зависимости от выбора пользователя, сортируем массив, передавая в 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