Untitled
unknown
plain_text
2 years ago
20 kB
4
Indexable
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ Лабораторная работа №2 по дисциплине «Программирование» Структурированный тип Группа: АВТ-041 Студенты: Кукарцева О., Кучинская А. Преподаватель: Балакин В. НОВОСИБИРСК 2021 Задание Определить структурированный тип и набор функций для работы с таблицей записей, реализованной в массиве структур. В перечень функций входят: ● ввод записи таблицы с клавиатуры; ● загрузка и сохранение таблицы в текстовом файле; ● просмотр таблицы; ● сортировка таблицы в порядке возрастания заданного поля; ● поиск в таблице элемента с заданным значением поля или с наиболее близким к нему по значению; ● удаление записи; ● изменение (редактирование) записи; ● вычисление с проверкой и использованием всех записей по заданному условию и формуле (например, общая сумма на всех счетах). Перечень полей структурированной переменной: Фамилия, номер счета, сумма на счете, дата последнего изменения. Теоретические сведения Основная идея алгоритма: Все операции над данными производятся через функции, в главной функции создается файл, отрисовывается меню, производится выбор интересующей нас функции. Описание функций представлено ниже, после каждой из них. Проектирование программы «Составные части» программы ● Функция проверки на корректность даты (дня и месяца, ограничения на год нет) int checkDate(int dd, int mm) ● Функция добавления в таблицу одного пользователя: его фамилии, номера счета, суммы на счете и даты void setuser(struct table *a, int i ) ● Функция добавления нескольких пользователей (вызывает функцию добавления одного пользователя) void setusers(struct table *TT, int n) ● Функция сохранения созданной таблицы (из полученных данных по пользователям) в файл void savefile(struct table TT, FILE *S1) ● Функция загрузки сохраненной таблицы из файла void loadfile(struct table *TT, FILE *S1) ● Функция вывода таблицы на экран void showtable(struct table TT) ● Функция удаления пользователя и его данных из таблицы void del(struct table *TT, int n) ● Функция подсчета общей суммы на всех счетах int sum(struct table TT) ● Функция поиска в строке char *find (char *p, char *q) ● Функция сравнения дат для последующего поиска int cmpDate(struct table *TT, int dd, int mm, int yy, int i) ● Функция сравнения дат для последующей сортировки int cmpDate2(struct table *TT, int i, int j) ● Функция поиска пользователя по одному из элементов записи таблицы void search(struct table TT) ● Функция сортировки записей о пользователях в таблице по заданному элементу void sortTable(struct table *TT) ● Функция отрисовки глобального меню со всеми доступными функциями void menu() Переменные: date структурированный тип даты d, m, y переменные структурированного типа даты: день, месяц, год user структурированный тип пользователя name[30], num, sum, date dd переменные структурированного типа пользователя: фамилия, номер счета, сумма на счете, дата table структурированный тип таблицы user TBL[100], n переменные структурированного типа таблицы: пользователи, их количество dd, mm введенные с клавиатуры дата и месяц для поиска в таблице i, j переменные-счетчики a, TT формальные переменные структурированного типа таблицы S1 файл, с которым идет работа sum переменная для подсчета общей суммы на счетах p, q переменные для поиска заданного элемента в таблице key[15] переменная для ввода искомой фамилии в таблице n, mode переменные для выбора интересующей функции из меню k, p переменные оператора ветвления cc переменная для обмена (“трех стаканов”) n, m переменные для ввода параметров в глобальном меню (целочисленные) Примеры работы программы Рисунок 1. Пункты меню 1 и 3: запись с клавиатуры записей о пользователях и сохранение данных в файл Рисунок 2. Пункты меню 2 и 4: загрузка таблицы из файла и вывод таблицы на экран Рисунок 3. Пункт меню 7: удаление записи пользователя Рисунок 4. Пункт меню 5: сортировка по выбранному элементу - фамилии Рисунок 5. Пункт меню 5: сортировка по выбранному элементу - дате Рисунок 6. Пункт меню 5: сортировка по выбранному элементу - номеру счета Рисунок 7. Пункт меню 5: сортировка по выбранному элементу - сумме на счете Рисунок 8.1 Пункт меню 6: поиск по заданному элементу - фамилии Рисунок 8.2 Пункт меню 6: поиск по заданному элементу - фамилии (не найден элемент - ошибка) Рисунок 9. Пункт меню 6: поиск по заданному элементу - дате Рисунок 10. Пункт меню 6: поиск по заданному элементу - номеру счета или сумме Рисунок 11. Пункт меню 8: изменение записи пользователя Рисунок 12. Пункт меню 9: подсчет суммы на всех счетах пользователей Выводы Использование структурированного типа позволяет создавать и редактировать простые таблицы (возможность объединения разнотипных элементов). Также стоит отметить «наглядность» структурированного типа: он позволяет обращаться к элементам по именам. Приложение 1. Текст программы с комментариями #include <stdio.h> #include <stdlib.h> #include <string.h> struct date // Setting the structured type of date { int d; int m; int y; }; struct user // Setting the structured type of user { char name[30]; int num; int sum; struct date dd; }; struct table // Setting the structured type of table { struct user TBL[100]; int n; }; int checkDate(int dd, int mm) // Function for checking the correctness of the entered date { if (mm > 12 || mm < 1) return 0; if (dd > (30 + ((mm + (mm / 8)) % 2)) || dd < 1) return 0; if (mm == 2 && dd > 28) return 0; return 1; } void setuser(struct table *a, int i ) // Single user add function { printf("Enter surname: "); scanf("%s", a->TBL[i].name); printf("Enter account number: "); scanf("%d", &(a->TBL[i].num)); printf("Enter the invoice amount: "); scanf("%d", &(a->TBL[i].sum)); printf("Enter a day "); scanf("%d", &(a->TBL[i].dd.d)); printf("Enter a month "); scanf("%d", &(a->TBL[i].dd.m)); printf("Enter a year "); scanf("%d", &(a->TBL[i].dd.y)); if (checkDate(a->TBL[i].dd.d, a->TBL[i].dd.m) == 0) { printf("Wrong date \n"); setuser(&a, i); } } void setusers(struct table *TT, int n ) // Multiple user add function { for (int i = TT->n; i < TT->n+n; i++) // Сycle of user input from keyboard { setuser(TT, i); } TT->n+=n; } void savefile(struct table TT, FILE *S1) // {The function of saving the created table to a file S1 = fopen("S1.txt","w"); for (int i = 0; i < TT.n; i++) // File save cycle { fprintf(S1, "%s ", TT.TBL[i].name); fprintf(S1,"%d ", TT.TBL[i].num); fprintf(S1,"%d ", TT.TBL[i].sum); fprintf(S1,"%d %d %d\n", TT.TBL[i].dd.d, TT.TBL[i].dd.m, TT.TBL[i].dd.y); } fclose(S1); } void loadfile(struct table *TT, FILE *S1) // The function of loading a table from a file { int i = 0; if ((S1 = fopen("S1.txt", "r")) == NULL) { printf ("File wasn't open\n"); system ("pause"); } else { while (!feof(S1)) // file load cycle { fscanf(S1, "%s %d %d %d %d %d\n", TT->TBL[i].name, &TT->TBL[i].num, &TT->TBL[i].sum, &TT->TBL[i].dd.d, &TT->TBL[i].dd.m, &TT->TBL[i].dd.y); TT->n++; i++; } } fclose(S1); } void showtable(struct table TT) // Function of displaying a table with users on the screen { for (int i = 0; i < TT.n; i++) // console output cycle { printf("User %d \n", i+1); printf("Last name: %s \n", TT.TBL[i].name); printf("Account number: %d \n", TT.TBL[i].num); printf("Invoice amount: %d \n", TT.TBL[i].sum); printf("Date: %d.%d.%d \n\n", TT.TBL[i].dd.d, TT.TBL[i].dd.m, TT.TBL[i].dd.y); } } void del(struct table *TT, int n) // Function for removing a user from a table { for (int i = n; i < TT->n; i++) // cycle of shift starting from the deleted element { TT->TBL[i] = TT->TBL[i+1]; } (TT->n)--; } int sum(struct table TT) // Function for calculating the amount on all accounts { int sum = 0; for (int i = 0; i < TT.n; i++) // Sum counting cycle sum+= TT.TBL[i].sum; return sum; } char *find (char *p, char *q) // Function for searching in a string { int i; for (; *p!='\0'; p++) // Pairwise comparison before finding a discrepancy { for (i = 0; q[i]!= '\0' && q[i] == p[i]; i++); if (q[i] == '\0') return p; // End of substring - success, otherwise - continue searching } return NULL; } int cmpDate(struct table *TT, int dd, int mm, int yy, int i) // Date comparison function for table lookup { if (yy != TT->TBL[i].dd.y) return yy - TT->TBL[i].dd.y; if (mm != TT->TBL[i].dd.m) return mm - TT->TBL[i].dd.m; if (dd != TT->TBL[i].dd.d) return dd - TT->TBL[i].dd.d; return 0; } int cmpDate2(struct table *TT, int i, int j) // Date comparison function for subsequent sorting { if (TT->TBL[j].dd.y != TT->TBL[i].dd.y) return TT->TBL[j].dd.y - TT->TBL[i].dd.y; if (TT->TBL[j].dd.m != TT->TBL[i].dd.m) return TT->TBL[j].dd.m - TT->TBL[i].dd.m; if (TT->TBL[j].dd.d != TT->TBL[i].dd.d) return TT->TBL[j].dd.d - TT->TBL[i].dd.d; return 0; } void search(struct table TT) // Table search function { int dd, mm, yy; printf("[0] Search by last name\n"); printf("[1] Search by date\n"); printf("[2] Search by account number or amount\n"); printf("Enter the operation number: "); int n, p = 0; scanf("%d", &n); char key[15]; switch(n) { case 0: // Search by last name printf("Insert the last name\n"); scanf("%s", key); printf("Found on your request: "); for (int i = 0; i < TT.n; i++) // Cycle for searching by last name { if (find(TT.TBL[i].name, key)) { p = 1; printf("\nUser %d \n", i+1); printf("Last name: %s \n", TT.TBL[i].name); printf("Account number: %d \n", TT.TBL[i].num); printf("Invoice amount: %d \n", TT.TBL[i].sum); printf("Date: %d.%d.%d \n\n", TT.TBL[i].dd.d, TT.TBL[i].dd.m, TT.TBL[i].dd.y); } } if(p == 0) printf("Not found\n"); system ("pause"); break; case 1: // Search by date printf("Insert the day, month, year\n"); scanf("%d %d %d", &dd, &mm, &yy); for(int i = 0; i < TT.n; i++) // Cycle for searching by date { if (!(cmpDate(&TT, dd, mm, yy, i))) { p = 1; printf("\nUser %d \n", i+1); printf("Last name: %s \n", TT.TBL[i].name); printf("Account number: %d \n", TT.TBL[i].num); printf("Invoice amount: %d \n", TT.TBL[i].sum); printf("Date: %d.%d.%d \n\n", TT.TBL[i].dd.d, TT.TBL[i].dd.m, TT.TBL[i].dd.y); } } if(p == 0) printf("Not found\n"); system("pause"); break; case 2: // Search by account or number printf("Insert the number or amount\n"); scanf("%s", key); int k; printf("Found on your request: "); k = atoi(key); for (int i = 0; i < TT.n; i++) // Cycle for searching by account or number { if (k == TT.TBL[i].num || k == TT.TBL[i].sum) // Exact match { p = 1; printf("\nUser %d \n", i+1); printf("Last name: %s \n", TT.TBL[i].name); printf("Account number: %d \n", TT.TBL[i].num); printf("Invoice amount: %d \n", TT.TBL[i].sum); printf("Date: %d.%d.%d \n\n", TT.TBL[i].dd.d, TT.TBL[i].dd.m, TT.TBL[i].dd.y); } else { if ((k > TT.TBL[i].num - 10 && k < TT.TBL[i].num + 10) || (k > TT.TBL[i].sum-10 && k <TT.TBL[i].sum + 10)) // Approximate match { p = 1; printf("\nUser %d \n", i+1); printf("Last name: %s \n", TT.TBL[i].name); printf("Account number: %d \n", TT.TBL[i].num); printf("Invoice amount: %d \n", TT.TBL[i].sum); printf("Date: %d.%d.%d \n\n", TT.TBL[i].dd.d, TT.TBL[i].dd.m, TT.TBL[i].dd.y); } } } if (p == 0) printf("Not found\n"); system ("pause"); break; default: printf("Incorrect value entered, repeat the operation\n"); break; } } void sortTable(struct table *TT) // Comparison function for table elements { int i, j, k, mode; printf("[0] Sort by last name\n"); printf("[1] Sort by date\n"); printf("[2] Sort by account number\n"); printf("[3] Sort by amount\n"); printf("Enter the operation number: "); scanf("%d", &mode); switch(mode) { case 0: // Sort by amount for (int i = 0; i < (TT->n)-1; i++) { for (int j = i+1; j < TT->n; j++) // Cycle for sorting by amount if (strcmp(TT->TBL[j].name,TT->TBL[i].name) < 0) { struct user cc = TT->TBL[i]; TT->TBL[i] = TT->TBL[j]; TT->TBL[j] = cc; } } break; case 1: // Sort by date for (int i = 0; i < (TT->n)-1; i++)// Cycle for sorting by date { for (int j = i+1; j < TT->n; j++) if (cmpDate2(TT, i, j) < 0) { struct user cc = TT->TBL[i]; TT->TBL[i] = TT->TBL[j]; TT->TBL[j] = cc; } } break; case 2:// Sort by number for (int i = 0; i < (TT->n)-1; i++) // Cycle for sorting by number { for (int j = i + 1; j < TT->n; j++) if (TT->TBL[j].num < TT->TBL[i].num) { struct user cc = TT->TBL[i]; TT->TBL[i] = TT->TBL[j]; TT->TBL[j] = cc; } } break; case 3: // Sort by amount for (int i = 0; i < (TT->n)-1; i++) { for (int j = i+1; j < TT->n; j++) // Cycle for sorting by amount if (TT->TBL[j].sum < TT->TBL[i].sum) { struct user cc = TT->TBL[i]; TT->TBL[i] = TT->TBL[j]; TT->TBL[j] = cc; } } break; default: printf("Incorrect value entered, repeat the operation\n"); break; } } void menu() // Global menu function { printf("[1] Insert the clients\n"); printf("[2] Upload the table\n"); printf("[3] Save the table\n"); printf("[4] Show the table\n"); printf("[5] Sort the table\n"); printf("[6] Search entry in table\n"); printf("[7] Delete entry\n"); printf("[8] Change entries\n"); printf("[9] Total amount on accounts\n"); printf("[0] Exit\n"); } int main() { struct table TT; menu(); FILE *S1; int input; TT.n = 0; int n, m; while (1) { printf("\nWhat do you want to do?\n "); scanf("%d", &input); if (input == 0) break; switch (input) { case 1: // Insert the clients printf("How many clients do you want to add\n"); scanf("%d", &n); setusers(&TT, n); break; case 2: // Upload the table loadfile(&TT, S1); break; case 3: // Save the table savefile(TT, S1); printf("Written successfully \n"); break; case 4: // Show the table showtable(TT); break; case 5: // Sort the table sortTable(&TT); break; case 6: search(TT); // Search entry in table break; case 7: // Delete entry printf("Which client do you want to delete? Select a number from 1 to %d ", TT.n); scanf("%d", &m); del(&TT, m-1); break; case 8: // Change entries printf("Which client do you want to change? Select a number from 1 to %d ", TT.n); scanf("%d", &n); setuser(&TT, n-1); break; case 9: // Total amount on accounts printf("Total amount on accounts = %d", sum(TT)); break; default: break; } } system("pause"); }
Editor is loading...