Програмирање 2/К3 2016
Zadatak
Napisati program na programskom jeziku C koji vrši određenu obradu na datotekom korisnika i datotekom njihovih akcija. U svakom redu datoteke korisnici.txt zapisani su podaci o jednom korisniku u sledećem formatu:
- username email
- username - korisničko ime, najviše 30 znakova
- email - email adresa korisnika, najviše 30 znakova
Username i email su jedinstveni podaci i pojavljuju se u najviše jednom redu. U svakom redu datoteke logs.txt nalaze se podaci o istoriji prijavljivanja i odjavljivanja korisnika na sistem u formatu:
e-mail akcija vreme
- e-mail - email adresa korisnika
- akcija - oznaka “p” ili “o” (p - prijava, o - odjava)
- vreme - trenutak u kome se akcija izvršila (ceo broj)
Jedan korisnik se može više puta prijaviti i odjaviti sa sistema. Informacije o korisnicima se čuvaju pomoću sledećih struktura:
typedef struct user {
char username[31], email[31];
int time;
} User;
typedef struct node {
User user;
struct node *next;
} Node;
Deklaracije ovih tipove se nalaze u datoteci type.h i nju je potrebno uključiti svugde gde se koriste ovi tipovi.
Prva funkcija
Realizovati funkciju Node* read_users(); koja formira listu korisnika tako što u listu dodaje svakog pročitanog korisnika iz datoteke korisnici.txt. Funkcija kao povratnu vrednost vraća pokazivač na prvi element novoformirane liste.
#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;
}
Druga funkcija
Realizovati funkciju User update_time(Node *head); koja učitava podatake iz datoteke logs.txt i ažurira listu na osnovu email adrese, tako da za svakog korisnika bude izračunato ukupno vreme koje je proveo prijavljen na sistem. Pokazivač head pokazuje na prvi element liste korisnika. Potprogram treba da vrati korisnika koji je najviše vremena bio prijavljen na sistem. Ukoliko postoji više takvih korisnika vratiti onog čije je korisničko ime prvo u rastuće sortiranoj listi po korisničkom imenu.
#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;
}
Treća funkcija
Realizovati funkciju void deallocateList(Node *head); koja oslobađa memoriju koju je zauzela lista na čiji prvi element pokazuje pokazivač head.
#include <stdlib.h>
#include "type.h"
void deallocateList ( Node *head ) {
while(head)
{
Node* tmp = head;
head = head->next;
free(tmp);
}
}
Glavna funkcija
Korišćenjem prethodno realizovanih funkcija napisati glavni program koji učita korisnike iz datoteke korisnici.txt, ažurira njihova vremena provedena u sistemu na osnovu informacija iz datoteke logs.txt i ispiše informacije o korisniku koji je najviše vremena proveo u sistemu.
#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;
}