Програмирање 2/К3 2016
Задатак
Написати програм на програмском језику C који врши одређену обраду на датотеком корисника и датотеком њихових акција. У сваком реду датотеке корисници.тxт записани су подаци о једном кориснику у следећем формату:
- усернаме емаил
- усернаме - корисничко име, највише 30 знакова
- емаил - емаил адреса корисника, највише 30 знакова
Усернаме и емаил су јединствени подаци и појављују се у највише једном реду. У сваком реду датотеке логс.тxт налазе се подаци о историји пријављивања и одјављивања корисника на систем у формату:
е-маил акција време
- е-маил - емаил адреса корисника
- акција - ознака “п” или “о” (п - пријава, о - одјава)
- време - тренутак у коме се акција извршила (цео број)
Један корисник се може више пута пријавити и одјавити са система. Информације о корисницима се чувају помоћу следећих структура:
typedef struct user {
char username[31], email[31];
int time;
} User;
typedef struct node {
User user;
struct node *next;
} Node;
Декларације ових типове се налазе у датотеци тyпе.х и њу је потребно укључити свугде где се користе ови типови.
Прва функција
Реализовати функцију Ноде* реад_усерс(); која формира листу корисника тако што у листу додаје сваког прочитаног корисника из датотеке корисници.тxт. Функција као повратну вредност враћа показивач на први елемент новоформиране листе.
#include <stdio.h>
#include <stdlib.h>
#include "type.h"
Node* readUsers ( ) {
FILE *in = fopen("korisnici.txt", "r");
Node *head = NULL, *tail = head, *tmp;
User u;
while(fscanf(in, "%s %s", u.username, u.email)==2)
{
tmp = malloc(sizeof(Node));
tmp->user = u;
tmp->user.time = 0;
tmp->next = NULL;
if(!head)
head = tmp;
else
tail->next = tmp;
tail = tmp;
}
fclose(in);
return head;
}
Друга функција
Реализовати функцију Усер упдате_тиме(Ноде *хеад); која учитава податаке из датотеке логс.тxт и ажурира листу на основу емаил адресе, тако да за сваког корисника буде израчунато укупно време које је провео пријављен на систем. Показивач хеад показује на први елемент листе корисника. Потпрограм треба да врати корисника који је највише времена био пријављен на систем. Уколико постоји више таквих корисника вратити оног чије је корисничко име прво у растуће сортираној листи по корисничком имену.
#include <stdio.h>
#include <stdlib.h>
#include "type.h"
#include <string.h>
User updateTime ( Node *head ) {
FILE *log = fopen("logs.txt", "r");
char email[31];
char operation;
int duration;
User max = head->user;
while(fscanf(log, "%s %c %d\n", email, &operation, &duration) == 3)
{
Node *tmp = head;
while(tmp && strcmp(tmp->user.email, email))
tmp = tmp->next;
if(tmp)
{
switch(operation)
{
case 'p': tmp->user.time -= duration;
break;
case 'o': tmp->user.time += duration;
break;
}
if(tmp->user.time > max.time ||
tmp->user.time == max.time && strcmp(tmp->user.username, max.username) > 1)
max = tmp->user;
}
}
fclose(log);
return max;
}
Трећа функција
Реализовати функцију воид деаллоцатеЛист(Ноде *хеад); која ослобађа меморију коју је заузела листа на чији први елемент показује показивач хеад.
#include <stdlib.h>
#include "type.h"
void deallocateList ( Node *head ) {
while(head)
{
Node* tmp = head;
head = head->next;
free(tmp);
}
}
Главна функција
Коришћењем претходно реализованих функција написати главни програм који учита кориснике из датотеке корисници.тxт, ажурира њихова времена проведена у систему на основу информација из датотеке логс.тxт и испише информације о кориснику који је највише времена провео у систему.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "type.h"
int main()
{
Node* users = readUsers();
User max = updateTime(users);
printf("%s %s %d", max.username, max.email, max.time);
deallocateList(users);
return 0;
}