Untitled

mail@pastecode.io avatar
unknown
plain_text
a year ago
20 kB
1
Indexable
Never
МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РОССИЙСКОЙ ФЕДЕРАЦИИ НОВОСИБИРСКИЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ





Лабораторная работа №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");
}