Вы находитесь на странице: 1из 41

Министерство науки и высшего образования Российской Федерации

Федеральное государственное автономное образовательное


учреждение высшего образования
«ЮЖНЫЙ ФЕДЕРАЛЬНЫЙ УНИВЕРСИТЕТ»

Инженерно-технологическая академия ЮФУ


Институт компьютерных технологий и информационной безопасности

Кафедра вычислительной техники

ЛАБОРАТОРНАЯ РАБОТА № 5

по курсу: «Алгоритмизация и программирование»

на тему: «Работа со структурами»

Выполнила

студентка группы Ктбо1- 3 Я. Р. Гончар

Проверил

Ассистент кафедры ВТ А. С. Зачитайлов

«15» декабря 2023г.

г. Таганрог
Содержание
Введение....................................................................................................................................................3
1. Теоретическая часть..............................................................................................................................4
1.1. Общие сведения о структурном типе данных..............................................................................4
1.2. Доступ к членам структуры............................................................................................................6
1.3. Присваивание структур..................................................................................................................7
1.4. Массивы структур...........................................................................................................................7
1.5. Передача членов структур функциям............................................................................................8
1.6. Передача целых структур функциям.............................................................................................9
1.7. Указатели на структуры................................................................................................................10
1.8. Массивы и структуры внутри структур........................................................................................11
2. Практическая часть..............................................................................................................................12
2.1 Разработка блок-схемы.................................................................................................................13
2.2 Листинг кода..................................................................................................................................13
2.3 Отладка...........................................................................................................................................24
Заключение..............................................................................................................................................26

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

Язык Си обеспечивает разнообразие типов данных. Базовыми типами


являются целые, вещественные числа и символы (литеры), разрешается
модификация базовых типов данных, а также создание пользовательских
типов. В языке используются стандартные типы данных: int, char, float,
double, а также используются массивы, структуры (записи), файлы. Кроме
того, имеется возможность конструирования очередей и списков.

Программы на языке Си компактны и гибки, в то же время в языке


отсутствуют средства контроля работы программиста. Язык Си как бы
«доверяет» разработчику и разрешает ему практически все действия. Из-за
этого Си нельзя считать языком надежного программирования, поскольку вся
ответственность за качество программы лежит на программисте. Поэтому
программист-разработчик должен хорошо знать особенности языка и его
реализации.

Цель лабораторной работы:

1. освоить способы задания и методы обработки данных структурного


типа;
2. освоить инициализацию и присваивание структур, доступ к элементам
структур, понятие массива структур, указателей на структуры и
операции над указателями;
3. научить работать со сложными типами данных, каковыми являются
структуры данных.

3
1. Теоретическая часть
В языке программирования Си кроме стандартных форматов данных,
таких как простые переменные, указатели, массивы и пр., можно задавать
более сложные форматы данных, которые объединяются понятием
структуры. Обработка данных структурного типа сегодня занимает важное
место в профессиональном программировании.

1.1. Общие сведения о структурном типе данных


Структура — это совокупность переменных (возможно разного типа),
объединенных общим именем.

С помощью структур удобно размещать в смежных полях связанные


между собой элементы информации. Объявление структуры создает шаблон
(тип), который можно использовать для создания ее объектов, т.е.
экземпляров этой структуры. Переменные, из которых состоит структура,
называют ее членами. Члены структуры также называют элементами или
полями. Как правило, все члены структуры связаны друг с другом по смыслу.

Объявление (декларирование) структуры осуществляется с помощью


конструкции вида:

struct тег {

тип имя-члена;

тип имя-члена;

} переменные-структуры;

где тег - тип структуры. Тег или переменные-структуры могут быть


пропущены, но только не оба одновременно. Следующий пример
демонстрирует объявление структуры и несколько переменных этого же
типа.

struct addr {
4
char name[30];

char street[40];

char city[20];

char state [3] ,

unsigned long int zip;

} addr_info, binfo, cinfo,

Здесь addr_info, binfo и cinfo дополнительно объявленные переменные


того же типа.

Важно понимать, что каждая переменная-структура содержит


собственные копии членов структуры. Например, поле zip в binfo отличается
от поля zip в cinfo. Изменения к zip из binfo не повлияют на содержимое поля
zip, находящегося в cinfo.

Если объявляется одна переменная-структура (addr_info), то тег (addr)


структуры является лишним, что показано на примере ниже:

struct {

char name [30];

char street[40];

char city [20] ;

char state [3] ,

unsigned long int zip;

} addr_ihfo;

5
1.2. Доступ к членам структуры
Доступ к отдельным членам структуры осуществляется с помощью
оператора «точка». В общем виде использование оператора точка для
доступа к члену структуры имеет вид:

имя-объекта.имя-члена

Например, в выражении:

addr_info.zip = 347900;

полю zip переменной-структуре addr_info присваивается почтовый индекс


«347900».

Вывод почтового индекса на экран имеет следующий вид:

printf ("%d", addr_inf о. zip) ,

Точно так же в вызове gets () можно использовать массив символов


addr__inf о. name:

gets(addr_info.name);

Таким образом, в начало name передается указатель на символьную


строку.

Так как name является массивом символов, то для получения доступа к


отдельным символам в массиве addr_info.name можно использовать индексы
вместе с name. Например, можно посимвольно вывести на экран содержимое
addr_inf о. name с помощью следующего кода:

for(t=0,- addr_info.name[t] ; ++t)

putchar(addr_info.name[t]);

Следует заметить, что индексируется именно name, а не addrJLnfо. Также


следует иметь в виду, что addr_infо — имя всего объекта-структуры, a name
6
это имя элемента самой структуры. Таким образом, если требуется
индексировать элемент структуры, то индекс необходимо указывать после
имени этого элемента.

1.3. Присваивание структур


Информация, которая находится в одной структуре, может быть
присвоена другой структуре того же типа при помощи единственного
оператора присваивания. Пример присваивания структур показан ниже:
#include

int main(void) {

struct {

int a; int b;

} x, y;

x.a = 10;

y = x; // присваение одной структуры другой

printf("%d", у.a); return 0; }

После присвоения в у. а будет храниться значение 10.

1.4. Массивы структур


Структуры можно образовывать в массивы, для чего нужно объявить
массив структур. При этом вначале необходимо определить структуру, а
затем объявить переменную массива этого же типа.

Пример. Объявить 100-элементный массив структур типа addr:

struct addr addr_list[99] ;

Это выражение создает 100 наборов переменных, каждый из которых


организован в соответствии со структурой addr.
7
Следующий пример выводит на экран почтовый индекс из третьей
структуры массива addr_list:

printf (" %d", addrJList [2] . zip) ;

Следует иметь в виду, что индексирование в массивах структур


начинается с нулевого элемента.

Рассмотрим еще один пример:

addrlist [2] .name[0] = 'X';

Здесь первому символу члена name, находящегося в фетьей структуре из


addrJList, присваивается значение 'X'.

1.5. Передача членов структур функциям


Пусть определена структура f red с переменной mike:

struct fred {

char x;

int у;

float z;

char s [10] ;

} mike;

Ниже показана подстановка в функции в качестве параметров членов


структуры mike:

func(mike.x); // передается символьное значение х

func2(mike.y); // передается целое значение у

Если же нужно передать адрес отдельного члена структуры, то перед


именем структуры должен находиться оператор &. Например, чтобы

8
передать адреса членов структуры mike, нужно использовать следующее
выражения:

func(&mike.х); // передается адрес символа х

func2_(&mike.y); // передается адрес целого у

fипсЗ(&mike.z); // пер-ся адрес члена z с точкой

func4 (mike.s); // передается адрес строки s

func(Sniike.s[21]); // передается адрес символа в s[2]

Следует обратить внимание, что оператор & стоит непосредственно перед


именем структуры, а не перед именем отдельного члена. Так как s уже
обозначает адрес, то написание & не требуется.

1.6. Передача целых структур функциям


Когда в качестве аргумента функции используется структура, то для
передачи целой структуры используется обычный способ вызова по
значению. При этом надо соблюдать, чтобы структура и параметр функции
имели один и тот же тип. Например, в следующей программе и аргумент arg
и параметр parm объявляются с одним и тем же типом структуры.

#include
/ * Определение типа структуры. */
struct struct__type {
int a, b; char ch;
};
void fl(struct struct_type parm);
int main(void) {
struct struct_type arg;
arg.a = 1000,
f1(arg);

9
return 0; }
void fl(struct struct_type parm) {
printf("%d", parm.a); }
При объявлении параметров, являющихся структурами объявление
типа структуры должно быть глобальным, чтобы структурный тип можно
было использовать во всей программе. Например, если бы struct_type был бы
объявлен внутри main (), то этот тип не был бы виден в f1().

1.7. Указатели на структуры


В языке Си указатели на структуры имеют некоторые особенности.
Объявление указателя на структуру объявляется с помощью звездочки *,
которую помещают перед именем переменной структуры. Например, для
ранее определенной структуры - addr следующее выражение объявляет
addrjpointer указателем на данные этого типа, т.е. на данные типа addr:

struc t addr *addr_pointer;

Указатели на структуры используются тогда, когда структура


передается функции с помощью вызова по ссылке или создаются связанные
друг с другом списки и другие структуры с динамическими данными.

Рассмотрим первый случай. При передаче структур функциям ее


предварительно нужно поместить в стек. Если в структуре имеется большое
число членов и/или члены сами являются массивами, то при передаче
структур функциям потребуются дополнительные ресурсы времени и памяти.
Поэтому с целью экономии ресурсов нужно передавать не саму структуру, а
указатель на нее.

Таким образом, когда функции передается указатель на структуру, то в


стек попадает только адрес структуры и вызовы функции выполняются
быстро.

10
Для того чтобы получить адрес переменной-структуры, необходимо
перед ее именем поместить оператор &. Следующий пример демонстрирует
такую передачу:

struct bal {

float balance; char name [80] ; }

person; struct bal *p; // объявление указателя на структуру

Адрес структуры person можно присвоить указателю р:

р = Sperson;

Для получения доступа к членам структуры с помощью указателя


необходимо использовать оператор стрелка (->).

Например:

р- >balance

Оператор стрелки применяется вместо оператора точки, если для


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

1.8. Массивы и структуры внутри структур


Членом структуры может быть или простая переменная, например,
типа in t или double, или составной (не скалярный) тип. В языке Си
составными типами являются массивы и структуры.

Члены структуры, которые являются массивами, можно считать такими


же членами структуры, как и те, что нам известны из предыдущих примеров.
Например:

struct X {

int а[10] [101; /* массив 10 х 10 из целых значений "/

float b; } у;

11
Здесь целый элемент с индексами 3. 7 из массива а, находящегося в
структуре у, обозначается таким образом: У-а[3] [7].

Когда структура является членом другой структуры, то она называется


вложенной. Например, в следующем примере: структура address вложена в
emp:

struct emp {
struct addr address; /* аижеикая структурй */
float wage; } worker;
Здесь структура была определена как имеющая два члена. Первым
является структура типа addr, в которой находится адрес работника. Второй
член — это wage, где находятся данные по его зарплате. В следующем
фрагменте программы элементу zip из .аddress присваивается значение
347900. worker.address.zip = 347900.

Таким образом, в каждой структуре любой член обозначают с


помощью тех структур, в которые он вложен, начиная от самых общих и
заканчивая той структурой, непосредственно- в которой он находится. В
соответствие со стандартом С89 структуры могут быть вложенными вплоть
до 15-го уровня. А стандарт С99 допускает уровень вложенности до 63-го
включительно.

2. Практическая часть
1) Написать программу, которая записывает с клавиатуры в файл
структуру согласно варианту 9 задания. В качестве разделителя полей
структуры использовать символ табуляции. В программе реализовать: а)
дополнение существующего массива структур новыми структурами;

б) поиск структуры с заданным значением выбранного элемента;

в) вывод на экран содержимого массива структур;

г) упорядочение массива структур по заданному полю (элементу),


например государство по численности.
12
2.1. Разработка блок-схемы

Рисунок 1 – Основная блок-схема.

2.2. Листинг кода


#include <locale.h>

#include<openssl/sha.h>

#include <stdio.h>

#include<string.h>
13
#include<stdlib.h>

#include <sys/types.h>

#include<wchar.h>

#include <ncurses.h>

#include <unistd.h> /* only for sleep() */

const char* AUTO_TYPE[] = {"Легковой", "Грузовой", "Джип",


"Автобус"};

FILE* AUTOS;

ssize_t* INDEXES;

int INDEXES_SIZE;

struct SFile{

char label[4]; // Must be CTF

int len;

unsigned char hash[32];

};

typedef struct {

int region;

int number;

wchar_t series[3];

}reg_number;

14
typedef struct {

unsigned char B;

unsigned char G;

unsigned char R;

} color;

struct Auto {

ssize_t struct_size;

ssize_t count;

ssize_t auto_gender_size;

color color; // Цвет

reg_number auto_reg;

int dors_count;

char auto_type;

int price;

unsigned char type;

char* auto_gender;

};

void p_hash(unsigned char hash[32])

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

printf("%x ", hash[i]);

printf("\n");

}
15
int file_hash(FILE* F, unsigned char hash[32])

SHA256_CTX sha_contex;

SHA256_Init(&sha_contex);

char buff[32];

fseek(F, sizeof(struct SFile), SEEK_SET);

while(fread(buff, 1, 32, F))

SHA256_Update(&sha_contex, buff, 32);

SHA256_Final(hash, &sha_contex);

printf(" Hash is "); p_hash(hash);

return 1;

struct Auto* get_new_auto(void)

struct Auto* new_auto = malloc(sizeof(struct Auto));

char string[256];
16
printf("Введите марку автомобиля [до 256 символов]:\n");

fgets(string, 256, stdin);

int len = strlen(string);

new_auto->auto_gender = (char*)malloc(len);

memcpy(new_auto->auto_gender, string, len);

new_auto->auto_gender[len - 1] = '\0';

printf("'%s'\n", new_auto->auto_gender);

printf("Введите цвет в hex формате RRGGBB\n");

scanf("%x", &new_auto->color); // Platform specific!

printf("R %d G %d B %d\n", new_auto->color.R, new_auto->color.G,


new_auto->color.B);

//printf("\\x1b[38;2;%d;%d;%dm КраСИвЫЙ Цвет!\\x1b[0m\n",


new_auto->color.R, new_auto->color.G, new_auto->color.B);

printf("\x1b[38;2;%d;%d;%dm КраСИвЫЙ Цвет!\x1b[0m\n",


new_auto->color.R, new_auto->color.G, new_auto->color.B);

reg_number* rn = &new_auto->auto_reg;

printf("Введите регистрационный номер:\n");

series:

printf(" Серия [3 буквы]: ");

scanf("%s", string);

mbstowcs(rn->series,string,3);
17
for(int i = 0; i < 3; i++)

switch(rn->series[i])

case L'А': case L'Б': case L'В': case L'Г': case L'Д': case L'Е': case
L'Ё': case L'Ж': case L'З': case L'И': case L'Й': case L'К': case L'Л': case
L'М': case L'Н': case L'О': case L'П': case L'Р': case L'С': case L'Т': case
L'У': case L'Ф': case L'Х': case L'Ц': case L'Ч': case L'Ш': case L'Щ': case
L'Э': case L'Ю': case L'Я':

continue;

default:

printf(" Нужно ввести 3 БОЛЬШИЕ русские буквы!\n");

goto series;

num:

printf(" Номер регистрации: ");

scanf("%d", &rn->number);

if(rn->number < 100 || rn->number > 999)

goto num;

printf(" Номер региона регистрации: ");

scanf("%d", &rn->region);

printf("Число дверей: ");

scanf("%d", &new_auto->dors_count);

18
select_type:

printf("Тип автомобиля:\n 1. Легковой\n 2. Грузовой\n 3. Джип\n


4.Автобус\n");

scanf("%hhd", &new_auto->type);

if(new_auto->type > 4)

goto select_type;

printf("Цена: ");

scanf("%d", &new_auto->price);

new_auto->auto_gender_size = strlen(new_auto->auto_gender);

new_auto->struct_size = sizeof(struct Auto) + new_auto-


>auto_gender_size - sizeof(char*);

//printf("\n Размер: %ld, %ld %ld\n",new_auto->struct_size,


sizeof(new_auto->auto_gender), new_auto->auto_gender_size);

printf("\nДлина строки %ld\n", strlen(new_auto->auto_gender));

long int al = sizeof(*new_auto) - sizeof(char*) + strlen(new_auto-


>auto_gender);

printf("Размер: %ld\n", al);

printf("\n");

return new_auto;

void print_auto_info(struct Auto *new_auto)

printf("Марка: '%s'\n", new_auto->auto_gender);

19
printf("Цвет: R %d G %d B %d\n", new_auto->color.R, new_auto-
>color.G, new_auto->color.B);

printf("\x1b[38;2;%d;%d;%dm КраСИвЫЙ Цвет!\x1b[0m\n",


new_auto->color.R, new_auto->color.G, new_auto->color.B);

printf("Регистрационный номер:\n");

printf(" Серия : %ls\n", new_auto->auto_reg.series);

printf(" Номер регистрации: %d\n", new_auto->auto_reg.number);

printf(" Номер региона регистрации: %d\n", new_auto-


>auto_reg.region);

printf("Число дверей: %d\n", new_auto->dors_count);

printf("Тип автомобиля: %s\n", AUTO_TYPE[new_auto->type-1]);

printf("Цена: %d, рублей.\n", new_auto->price);

FILE* ctf_open_file(const char* filename, struct SFile* meta, const char*


f_op)

FILE* Autos;

20
if(!meta)

struct SFile m;

meta = &m;

Autos = fopen(filename, "rb");

if(!Autos)

printf("Не могу открыть файл %s для чтения, создам новый\n",


filename);

Autos = fopen(filename, "wb");

if(!Autos)

return NULL;

else

printf("Файл регистрации - Autos.ctf\n");

meta->len = 0;

meta->label[0] = 'C';

meta->label[1] = 'T';

meta->label[2] = 'F';

meta->label[3] = '\0';

fwrite(meta, sizeof(*meta), 1, Autos); // Инициализация файла

printf("Инициалировали %s\n", filename);

21
goto ret;

printf("Открыл %s\n", filename);

fread(meta, sizeof(struct SFile), 1, Autos);

printf("Метка: %s\n", meta->label);

if(strcmp("CTF", meta->label))

printf(" E:сломанная метка\n");

return NULL;

printf("Длина: %d\n", meta->len);

if(meta->len > 0)

unsigned char this_hash[32];

file_hash(Autos, this_hash);

p_hash(this_hash);

p_hash(meta->hash);

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

if(meta->hash[i] != this_hash[i])

printf(" E: Сломааный кэш!\n");

return NULL;

}
22
}

printf("КэШ свалидировался!\n");

ret:

fclose(Autos);

return fopen(filename, f_op);

void update_file_hash(FILE* file)

struct SFile meta;

fseek(file, 0, SEEK_SET);

fread(&meta, sizeof(struct SFile), 1, file);

printf("Phash %ld\n", (long int)meta.hash);

unsigned char hash[32];

file_hash(file, hash);

memcpy(meta.hash, hash, 32);

printf("hash %ld\n", (long int)hash);

fseek(file, 0, SEEK_SET);

fwrite(&meta, sizeof(struct SFile), 1, file);

int ctf_file_add(struct Auto* autos[], ssize_t n, FILE* file)

{
23
struct SFile meta;

fseek(file, 0, SEEK_SET);

fread(&meta, sizeof(struct SFile), 1, file);

printf("ДлинаААА: %d, '%s'\n", meta.len, meta.label);

fseek(file, 0, SEEK_END);

for(ssize_t i = 0; i < n; i++)

if(!fwrite(autos[i], sizeof(*autos[i])-8, 1, file))

return 0;

fwrite(autos[i]->auto_gender, autos[i]->auto_gender_size, 1, file);

meta.len += 1;

printf("Add a car\n");

fseek(file, 0, SEEK_SET);

if(!fwrite(&meta, sizeof(struct SFile), 1, file))

printf("Can't write meta!\n");

fseek(file, 0, SEEK_SET);

fread(&meta, sizeof(struct SFile), 1, file);

update_file_hash(file);

return 1;

// Вернет массив смещений элементов

ssize_t* ctx_file_get_index_table(FILE* F, int* size)

struct SFile meta;


24
ssize_t struct_size;

fseek(F, 0, SEEK_SET);

fread(&meta, sizeof(struct SFile), 1, F);

ssize_t* indexes = (ssize_t*)malloc(sizeof(ssize_t)*meta.len);

for(int i = 0; i < meta.len; i++)

indexes[i] = ftell(F);

fread(&struct_size, sizeof(ssize_t), 1, F);

//printf(" Read size %ld, index is %ld\n", struct_size, indexes[i]);

if(fseek(F, struct_size - sizeof(char*), SEEK_CUR))

return NULL;

*size = meta.len;

return indexes;

void ctf_get_auto(FILE* F, ssize_t offset, struct Auto* a)

fseek(F, offset, SEEK_SET);

fread(a, sizeof(struct Auto) - sizeof(char*), 1, F);

a->auto_gender = (char*)malloc(a->auto_gender_size);

fread(a->auto_gender, a->auto_gender_size, 1, F);

25
void print_autos(ssize_t* indexes, int count, FILE* f)

struct Auto use_auto;

use_auto.auto_gender = NULL;

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

ctf_get_auto(f, indexes[i], &use_auto);

printf("====-------====\n");

print_auto_info(&use_auto);

printf("--------------\n");

void end_buffer()

int c;

do{

c = getchar();

}while(c != EOF && c != '\n' && c != '\r');

int cmp_name(ssize_t* i1, ssize_t* i2)

int ret;
26
struct Auto autos[2];

ctf_get_auto(AUTOS, *i1, &autos[0]);

ctf_get_auto(AUTOS, *i2, &autos[1]);

ret = strcmp(autos[0].auto_gender, autos[1].auto_gender);

free(autos[0].auto_gender);

free(autos[1].auto_gender);

printf(" SRET %d\n", ret);

return ret;

int cmp_color(ssize_t* i1, ssize_t* i2)

int ret;

struct Auto autos[2];

ctf_get_auto(AUTOS, *i1, &autos[0]);

ctf_get_auto(AUTOS, *i2, &autos[1]);

ret = (autos[0].color.R - autos[1].color.R) +

(autos[0].color.G - autos[1].color.G) +

(autos[0].color.B - autos[1].color.B);

free(autos[0].auto_gender);

free(autos[1].auto_gender);

return ret;

int cmp_reg_number(ssize_t* i1, ssize_t* i2)


27
{

int ret;

struct Auto autos[2];

ctf_get_auto(AUTOS, *i1, &autos[0]);

ctf_get_auto(AUTOS, *i2, &autos[1]);

reg_number r1 = autos[0].auto_reg;

reg_number r2 = autos[1].auto_reg;

ret = r2.number - r1.number + r2.region - r2.region + wcscmp(r1.series,


r2.series);

free(autos[0].auto_gender);

free(autos[1].auto_gender);

return ret;

int cmp_type(ssize_t* i1, ssize_t* i2)

int ret;

struct Auto autos[2];

ctf_get_auto(AUTOS, *i1, &autos[0]);

ctf_get_auto(AUTOS, *i2, &autos[1]);

ret = autos[1].auto_type - autos[0].auto_type;

free(autos[0].auto_gender);

free(autos[1].auto_gender);

return ret;

28
int cmp_price(ssize_t* i1, ssize_t* i2)

int ret;

struct Auto autos[2];

ctf_get_auto(AUTOS, *i1, &autos[0]);

ctf_get_auto(AUTOS, *i2, &autos[1]);

ret = autos[1].price - autos[0].price;

free(autos[0].auto_gender);

free(autos[1].auto_gender);

return ret;

void sort(int(*s_function)(const void* , const void* ))

INDEXES = ctx_file_get_index_table(AUTOS, &INDEXES_SIZE);

qsort(INDEXES, INDEXES_SIZE, sizeof(ssize_t), s_function);

print_autos(INDEXES, INDEXES_SIZE, AUTOS);

void field_search(int opti, char* filter)

INDEXES = ctx_file_get_index_table(AUTOS, &INDEXES_SIZE);


29
struct Auto s_auto;

int type;

color col;

int f;

wchar_t buf[20];

int region;

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

ctf_get_auto(AUTOS, INDEXES[i], &s_auto);

switch(opti)

case 1:

if(strstr(filter, s_auto.auto_gender))

print_auto_info(&s_auto);

break;

case 2:

sscanf(filter, "%ls %d %d",buf, &f, &region);

printf("PARSED: %d %d '%ls'\n", f, region, buf);

if(wcsstr(s_auto.auto_reg.series, buf) && f ==


s_auto.auto_reg.number && s_auto.auto_reg.region == region)

30
print_auto_info(&s_auto);

break;

case 3:

sscanf(filter, "%d", &type);

if(type == s_auto.type)

print_auto_info(&s_auto);

break;

case 4:

sscanf(filter, "%x", &col);

if(col.R == s_auto.color.R && col.G == s_auto.color.G && col.B ==


s_auto.color.B)

print_auto_info(&s_auto);

printf("\n");

break;

case 5:

sscanf(filter, "%d", &type);

if(type == s_auto.price)

print_auto_info(&s_auto);

break;

free(s_auto.auto_gender);

31
}

int main()

setlocale(LC_ALL, "ru_RU.utf8");

struct SFile meta;

AUTOS = ctf_open_file("Autos.ctf", &meta, "r+");

if(AUTOS)

printf("ОТКРЫЛИ ФАААЙЛЛ!\n");

else

return -1;

printf("LABEL %s\n", meta.label);

struct Auto* n_auto;

int n_autos_count = 0;

ssize_t* indexes;

int opti;

int run = 1;

char ch = 0;

char opt;

while(run)

32
printf("Выберите опцию: \n [1] Добавить автомобиль\n [2] Вывести
список авто \n [3] Вывести сортированный список авто\n [4] Поиск по
ключу\n [5] Выйти\n");

scanf("%d", &opti);

end_buffer();

switch(opti)

case 1:

add_auto:

end_buffer();

n_auto = get_new_auto();

ctf_file_add(&n_auto, 1, AUTOS);

free(n_auto->auto_gender);

free(n_auto);

meta.len += 1;

opti = 0;

break;

case 2:

indexes = ctx_file_get_index_table(AUTOS, &meta.len);

if(indexes)

print_autos(indexes, meta.len, AUTOS);

opti = 0;

break;

case 3:

printf("По какому полю сортировать?\n");


33
printf(" [1] Марка \n [2] Номер регистрации\n [3] Тип
автомобиля\n [4] Цвет\n [5] Цена\n >");

scanf("%d", &opti);

switch(opti)

case 1:

printf("MArk Sort\n");

sort(cmp_name);

break;

case 2:

sort(cmp_reg_number);

break;

case 3:

sort(cmp_type);

break;

case 4:

sort(cmp_color);

break;

case 5:

sort(cmp_price);

break;

opti = 0;

break;

34
case 4:

indexes = ctx_file_get_index_table(AUTOS, &meta.len);

printf("По какому полю искать?\n");

printf(" [1] Марка \n [2] Номер регистрации\n [3] Тип


автомобиля\n [4] Цвет\n [5] Цена\n >");

char* string = malloc(256);

fgets(string, 256, stdin);

sscanf(string, "%d", &opti);

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

if(string[i] == '\0' )

goto end;

if(string[i] == ' ')

string += i;

break;

printf("Opt %d, filter %s", opti, string);

field_search(opti, string);

opti = 0;

end:

break;

35
case 5:

fclose(AUTOS);

return 0;

fclose(AUTOS);

printf("REAL длина: %d\n", meta.len);

return 0;

2.3. Отладка

Рисунок 2 – Главное меню.

36
Рисунок 3 – Добавление нового авто

37
Рисунок 4 – Меню поиска и поиск

38
Рисунок 6 – Вывод всех объектов.

39
Рисунок 8 – Вывод всех строк из файла после сортировки по имени.

40
Заключение
В ходе лабораторной работы получены базовые сведения о средах и
средствах разработки языка программирования Си, структурах программ,
типах данных, массивах и работе с ними, строках, массивах символов,
файлах данных, простейших арифметических операциях, циклах, операциях
ввода/вывода, функциях, которые составляют основные структурные
компоненты языка для написания программ на языке Си.

Язык программирования Си занимает промежуточное положение


между языками высокого уровня и машинно-ориентированными языками и
рассмотрены особенности конструирования исходного кода программ.
Выработаны практические навыки программирования благодаря
использованию теоретических элементов к лабораторным работам.
Приобретены первичные технологические приемы программирования на
языке Си.

41

Вам также может понравиться