ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 24.06.2020
Просмотров: 103
Скачиваний: 3
МІНІСТЕРСТВО ОСВІТИ, НАУКИ МОЛОДІ ТА СПОРТУ УКРАЇНИ
НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ „ЛЬВІВСЬКА ПОЛІТЕХНІКА”
Кафедра ІСМ
Розрахункова робота
З дисципліни «Проблемно-орієнтоване програмування»
На тему “ Опрацювання структурованих даних засобами мови Сі ”
Виконав:
студент групи КН-25
Небельський В.В.
Прийняв:
асистент каф. ІСМ
Кравець П.О.
Львів 2011
ЗАВДАННЯ
Ввести з клавіатури масив рядків символів з даними про автомобілі: марка авто, номер, колір, прізвище власника, адреса власника, відмітка про техогляд. Виділити складові частини рядків та записати їх у відповідні поля масиву структур. Впорядкувати масив структур по номеру авто. Переписати масив структур у двонаправлений лінійний список динамічної пам’яті. Виключити зі списку дані про авто заданого номеру. Переписати список у текстовий файл. Вивести список і файл на екран у вигляді таблиці. Усі дії оформити у вигляді окремих функцій.
ТЕКСТ ПРОГРАМИ
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
typedef struct adres // структура для запису адреси
{ // у форматі:
char country[10]; // країна
char town[10]; // місто
char street[15]; // вулиця
}adres;
typedef struct car // Основна структура:
{
char mark[10]; // марка
char num[5]; // номер
char col[10]; // колір
char name[10]; // ім'я власника
adres adr; // його адреса
char teh[5]; // мітка про техогляд
}car;
typedef struct list // структура для формування Двонапрямленого Лінійного Списку [ДЛС]
{
car in;
struct list *next;
struct list *prev;
}list;
void read(car *a,int n);
void print(car *a,int n);
void printlist(list *a,list *q);
void sort(car *a,int n);
void fwrite(list *a,list *q);
void writefile(list *a,list *q);
list *makelist(list *a,list *q,car *b,int n);
list *del(list *l,list *q,list *r,int n);
list *head,*tail;
int main()
{
car *info;
int i,j,n;
list *lst,*q,*r;
printf("How many elements you wish to enter??? ");
scanf("%d",&n);
// Виділення динамічної пам'яті під:
info=(car*)calloc(n,sizeof(car)); // масив структур
lst=(list*)calloc(n,sizeof(list)); // двонапрямлений список
q=(list*)malloc(sizeof(list)); // допоміжний вказівник
r=(list*)malloc(sizeof(list)); // ще один
tail=(list*)malloc(sizeof(list)); // вказівник на хвіст ДЛС
head=(list*)malloc(sizeof(list)); // вказівник на голову ДЛС
read(info,n); /* Створення масиву структур */
sort(info,n); /* Його сортування за номером */
print(info,n); /* Вивід на екран */
lst=makelist(lst,q,info,n); // Створення ДЛС
lst=del(lst,q,r,n); // Видалення елементів із вказаним атрибутом
print(info,n);
printlist(tail,q); // Виведення списку на екран
fwrite(tail,q); // Запис у файл
system("pause");
}
list *makelist(list *a,list *q,car *b,int n) // Створення ДЛС
{
head=NULL; int i;
for (i=0;i<n;i++)
{
q=(list*)malloc(sizeof(list)); // додавання нових елементів
q->next=head; // відбувається з кінця списку
if (head!=NULL) head->prev=q; // <---
else tail=q;
head=q;
head->in=*(b+i);
}
head->prev=NULL;
return (head); // ф-я повертає вказівник на голову
}
list *del(list *l,list *q,list *r,int n) // Видалення елементів
{
char numb[5]; int i;
list *temp=(list*)malloc(sizeof(list));
printf("\n\t\tEnter number you wish to delete: ");
scanf("%s",&temp->in.num); // за вказаним номером
printf("\nYou want to delete %-5s: ",temp->in.num);
for (i=0;i<n;i++)
{
if (!strcmp( temp->in.num , l->in.num ))
{
if ( (l->prev)&&(l->next) ) // якщо елемент всередині списку
{
q=l->prev;
r=l->next;
l->next=NULL;
l->prev=NULL;
free(l);
q->next=r;
r->prev=q;
l=q->next;
}
else if ( (l->prev)&&(!(l->next) ) ) // якщо елемент є останнім
{
q=l->prev;
free(l);
l=q;
l->next=NULL;
tail=l;
}
else if ( (l->next)&&(!(l->prev) )) // якщо елемент є першим
{
q=l->next;
free(l);
l=q;
l->prev=NULL;
head=l;
}
else
printf("\nErr");
}
else l=l->next;
}
return head; // ф-я повертає вказівник на head
}
void printlist(list *a,list *q) // ф-я виводить дані списку на екран у вигляді таблиці
{
printf("\n\n\n\t\tHere is the final information:\n");
q=a;
while (q)
{
printf("\n%-10s %-5s %-10s %-10s %-10s %-10s %-15s %-5s",q->in.mark,q->in.num, q->in.col,q->in.name,q->in.adr.country,q->in.adr.town,q->in.adr.street,q->in.teh);
q=q->tail;
}
}
void read(car *a,int n) // ф-я для введення вхідної інформації
{
int i;
printf("\nEnter information in such way:\n");
printf("\nMark\tNumber\tColour\tName\tAdress(Country/Town/Street)\tTech(Yes/No)\n");
for(i=0;i<n;i++) scanf("%s%s%s%s%s%s%s%s",&(a+i)->mark,&(a+i)->num,&(a+i)->col, &(a+i)->name,&(a+i)->adr.country,&(a+i)->adr.town,&(a+i)->adr.street,&(a+i)->teh);
}
void print(car *a,int n) // ф-я виводить масив структур на екран у вигляді таблиці
{
int i;
printf("\n\tHere is the information (from list) :\n");
for(i=0;i<n;i++) printf("\n%-10s %-5s %-10s %-10s %-10s %-10s %-15s %-5s",(a+i)->mark,(a+i)->num,(a+i)->col,(a+i)->name,(a+i)->adr.country,(a+i)->adr.town,(a+i)->adr.street,(a+i)->teh);
}
void sort(car *a,int n) // ф-я для сортування масиву структур за номером машини
{
car tp;
int i,j;
for (i=0;i<n-1;i++)
for (j=i+1;j<n;j++)
if ( (strcmp ( (a+i)->num,(a+j)->num) ) >0)
{
tp=*(a+i);
*(a+i)=*(a+j);
*(a+j)=tp;
}
}
void fwrite(list *a,list *q) // ф-я для запису даних у файл
{ FILE *f;
q=a;
f=fopen("C:\\res.txt", "w+"); // режим w - для запису (файл створюється,якщо не існує)
while (q)
{
fprintf(f,"%-10s %-5s %-10s %-10s %-10s %-10s %-15s %-5s",q->in.mark,q->in.num,q->in.col,q->in.name,q->in.adr.country,q->in.adr.town,q->in.adr.street,q->in.teh);
fputc('\n',f); // перехід на новий рядок
q=q->tail;
}
fclose(f);
}
ОПИС ПРОГРАМИ
Розроблена програма має такий алгоритм роботи для виконання поставленої задачі:
-
Визначення кількості елементів
Користувач вводить бажану кількість елементів ( n ) і під цю
кількість виділяється відповідний об’єм ДП для оптимізації розміру програми.
-
Заповнення масиву структур
У циклі з параметром проводиться зчитування відповідних полів МС.
Ф-я називається read. Вхідними параметрами ф-ї є вказівник на масив структур і кількість елементів. Ф-я не повертає значення.
void
read(car *a,int
n) //
ф-я для введення вхідної інформації
{
int
i;
printf("\nEnter
information in such way:\n");
printf("\nMark\tNumber\tColour\tName\tAdress(Country/Town/Street)\tTech(Yes/No)\n");
for(i=0;i<n;i++)
scanf("%s%s%s%s%s%s%s%s",&(a+i)->mark,&(a+i)->num,&(a+i)->col,
&(a+i)->name,&(a+i)->adr.country,&(a+i)->adr.town,&(a+i)->adr.street,&(a+i)->teh);
}
-
Сортування масиву структур
Відповідно до завдання здійснюється сортування масиву структур за вказаним атрибутом, а саме номером авто.
Ф-я сортування називається sort. Вхідними параметрами ф-ї є вказівник на масив структур і кількість елементів. Сортування здійснюється методом бульбашки.
void
sort(car *a,int
n) //
ф-я для сортування масиву структур за
номером машини
{
car
tp;
int
i,j;
for
(i=0;i<n-1;i++)
for
(j=i+1;j<n;j++)
if
( (strcmp ( (a+i)->num,(a+j)->num) ) >0)
{
tp=*(a+i);
*(a+i)=*(a+j);
*(a+j)=tp;
} }
-
Створення двонаправленого лінійного списку
Виділяю пам'ять для розташування у ній ДЛС. Додавання нових елементів здійснюю з кінця так як вважаю цей метод оптимальнішим з огляду на розмір коду.
Ф-я, яка створює ДЛС називається makelist. Сама функція є вказівником і має такі вхідні параметри: 2 вказівники на структуру яка описує ДЛС (list *а і list *q), вказівник на масив структур з якого буде братися інформація (car *b) і кількість елементів (n). ДЛС створюю зправа наліво, тобто з кінця. Функція повертає вказівник на голову списку.
list
*makelist(list *a,list *q,car *b,int
n) //
Створення ДЛС
{
head=NULL;
int
i;
for
(i=0;i<n;i++)
{
q=(list*)malloc(sizeof(list)); //
додавання нових елементів
q->next=head; //
відбувається з кінця списку
if
(head!=NULL) head->prev=q; //
<---
else
tail=q;
head=q;
head->in=*(b+i);
}
head->prev=NULL;
return
(head); //
ф-я повертає вказівник на голову
}
-
Видалення зі списку вказаних елементів
Перш за все користувач вводить номер авто, які він бажає видалити з ДЛС. Починаючи з голови списку, я переглядаю поточний елемент ( а саме його поле з номером авто) і при співпадінні з введеним видаляю його, звільняючи тим самим об’єм ОП, яку він займав.
Ф-я, яка видаляє відповідні елементи з ДЛС називається del. Сама функція є вказівником і має такі вхідні параметри: 3 вказівники на структуру яка описує ДЛС (list *l, list *q і list *r), і кількість елементів (n). В залежності від розміщення елемента відбувається його видалення зі списку. Ф-я повертає вказівник на голову.
list
*del(list *l,list *q,list *r,int
n) //
Видалення елементів
{
.
. .
{
if
( (l->prev)&&(l->next) )
//
якщо елемент всередині списку
{
. . .
}
else
if
( (l->prev)&&(!(l->next) ) ) //
якщо елемент є останнім
{
. . .
}
else
if
( (l->next)&&(!(l->prev) )) //
якщо елемент є першим
{
. . .
}
printf("\nErr");
}
else
l=l->next;
}
return
head; //
ф-я повертає вказівник на head
}
-
Виведення на екран у вигляді таблиці відсортованого масиву структур і ДЛС
У циклі з параметром я виводжу введений і посортований масив структур. Крім того я виводжу ДЛС який, відповідно, є також відсортованим і без видалених елементів.
Ф-я, яка виводить елементи масиву структур на екран у вигляді таблиці називається print. Сама функція має такі вхідні параметри: вказівник на масив структур і кількість його елементів.
void
print(car *a,int
n) //
ф-я виводить масив структур на екран у
вигляді таблиці
{
int
i;
printf("\n\tHere
is the information (from
list) :\n");
for(i=0;i<n;i++)
printf("\n%-10s
%-5s %-10s %-10s %-10s %-10s %-15s
%-5s",(a+i)->mark,(a+i)->num,(a+i)->col,(a+i)->name,(a+i)->adr.country,(a+i)->adr.town,(a+i)->adr.street,(a+i)->teh);
}
-
Запис ДЛС у текстовий файл
Утворений двонаправлений лінійний список я записую у текстовий файл. Режим доступу до файлу « w+ » що дозволяє створити файл для запису й читання, якщо його не існує і перезаписати, якщо він відповідно існує.
КОНТРОЛЬНИЙ ПРИКЛАД
Рис.1. Діалог виконання програми
АНАЛІЗ РЕЗУЛЬТАТУ
Для демонстрації роботи програми в наведеному приклад було введено кількість елементів n = 7. Після цього були введені 7 стрічок з інформацією відповідно до вимог завдання. Видалення елементів відбувалося за номером «ZZX», яких у наведеному прикладі було 2. Після видалення відповідних структур я вивів на екран решти даних з ДЛС. Даний список я в результаті переписую у текстовий файл res.txt. Скріншоти демонструють правильність результату виконання.
Рис.2. Вміст файлу «res.txt»
ПЕРЕЛІК УМОВНИХ ПОЗНАЧЕНЬ
-
МС – Масив структур
-
ДП – Динамічна пам'ять
-
ОП – Оперативна пам'ять
-
ДЛС – Двонаправлений лінійний список
CПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ
-
Juan Soulie, «C and C++ Language Tutorial», 2008
-
В.В. Войтенко, А.В. Морозов, «C/C++ Теорія та практика», Житомир, 2004
-
Кравець П.О. , Методичні вказівки до лабораторних робіт з дисципліни «Проблемно-орієнтовані мови програмування», Львів, 2005
-
Дж.Макконел, «Основи сучасних алгоритмів», Москва, 2004
-
Кнут Д.Е. «Мистецтво програмування », Київ, 2007
ВИСНОВОК
Виконуючи дану лабораторну роботу я детально ознайомився із принципами роботи з структурованими даними. Навчився правильно їх ініціалізувати, виділяючи при цьому динамічну пам'ять, робити над ними операції сортування, додавання, зміни полів структур. Крім цього я закріпив навички роботи з файлами, так як вмію їх створювати, видаляти і редагувати.