ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 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»



























ПЕРЕЛІК УМОВНИХ ПОЗНАЧЕНЬ



  1. МС – Масив структур


  1. ДП – Динамічна пам'ять


  1. ОП – Оперативна пам'ять


  1. ДЛС – Двонаправлений лінійний список





































CПИСОК ВИКОРИСТАНОЇ ЛІТЕРАТУРИ



  1. Juan Soulie, «C and C++ Language Tutorial», 2008


  1. В.В. Войтенко, А.В. Морозов, «C/C++ Теорія та практика», Житомир, 2004


  1. Кравець П.О. , Методичні вказівки до лабораторних робіт з дисципліни «Проблемно-орієнтовані мови програмування», Львів, 2005


  1. Дж.Макконел, «Основи сучасних алгоритмів», Москва, 2004



  1. Кнут Д.Е. «Мистецтво програмування », Київ, 2007





































ВИСНОВОК

Виконуючи дану лабораторну роботу я детально ознайомився із принципами роботи з структурованими даними. Навчився правильно їх ініціалізувати, виділяючи при цьому динамічну пам'ять, робити над ними операції сортування, додавання, зміни полів структур. Крім цього я закріпив навички роботи з файлами, так як вмію їх створювати, видаляти і редагувати.




13