Untitled
unknown
plain_text
3 years ago
20 kB
5
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...