9511_project03

Command line program that parses a bank .csv file and generates and output file in format .csv or .xml containing the debits and credits of every user.
Index Commits Files Refs README LICENSE
commit 7de7356a1b085cf76c9818d475f1145e44a62a16
parent 2d69a1ac6e1ea828c60759db91c4ce26308d45b1
Author: klewer-martin <martin.cachari@gmail.com>
Date:   Wed, 28 Jul 2021 21:56:47 -0300

Update:

Diffstat:
MMakefile | 7++-----
Minclude/cla.h | 15++++++++-------
Minclude/io.h | 7+++----
Minclude/user.h | 18++++++------------
Minclude/vector.h | 2+-
Msource/cla.c | 54+++++++++++++++++++++++++-----------------------------
Msource/io.c | 143+++----------------------------------------------------------------------------
Msource/main.c | 156++++++++++++++++++--------------------------------------------------------------
Msource/user.c | 69++++++++++++++++++---------------------------------------------------
Msource/vector.c | 6++----
10 files changed, 103 insertions(+), 374 deletions(-)
diff --git a/Makefile b/Makefile
@@ -6,8 +6,8 @@ PROGNAME=main
 
 all: main clean
 
-main: cla.o status.o sort.o io.o main.o user.o vector.o
-    $(CC) $(CFLAGS) main.o cla.o status.o io.o sort.o user.o vector.o -o $(PROGNAME)
+main: cla.o status.o io.o main.o user.o vector.o
+    $(CC) $(CFLAGS) main.o cla.o status.o io.o user.o vector.o -o $(PROGNAME)
 
 main.o: $(HFOLDER)/cla.h $(HFOLDER)/status.h $(HFOLDER)/user.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/main.c
@@ -24,9 +24,6 @@ status.o: $(HFOLDER)/status.h
 io.o: $(HFOLDER)/status.h $(HFOLDER)/user.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/io.c
 
-sort.o: $(HFOLDER)/status.h $(HFOLDER)/user.h
-    $(CC) $(CFLAGS) -c $(SRCFOLDER)/sort.c
-
 user.o: $(HFOLDER)/status.h $(HFOLDER)/user.h
     $(CC) $(CFLAGS) -c $(SRCFOLDER)/user.c
 
diff --git a/include/cla.h b/include/cla.h
@@ -21,17 +21,18 @@ typedef enum {
 } flags_t;
 
 typedef struct {
-    char *fmt, *fi, *fo;
+    char *fmt;
+    FILE *fi, *fo;
     unsigned long ti, tf;
 } ADT_cla_t, *cla_t;
 
-status_t validate_arguments(int argc, char **argv);
-status_t check_flags_position(int argc, char **argv);
-status_t check_flags_repeated(int argc, char **argv);
+status_t validate_arguments(int, char **, cla_t);
+status_t check_flags_position(int, char **);
+status_t check_flags_repeated(int, char **);
 
-status_t cla_create(cla_t *cla);
-status_t cla_setup(int argc, char **argv, cla_t *cla);
-status_t cla_destroy(cla_t *cla);
+status_t cla_create(cla_t *);
+status_t cla_setup(int, char **, cla_t);
+status_t cla_destroy(cla_t);
 
 extern const char *available_flags[FLAGS_MAX];
 extern const char *available_formats[FORMATS_MAX];
diff --git a/include/io.h b/include/io.h
@@ -47,19 +47,18 @@
 /*     POS_DESC */
 /* } csv_pos_t; */
 
-status_t process_file(cla_t cla, user_t **users, size_t *i);
-
 status_t string_split(char *s, char **data, char *delim);
 
 status_t load_values(FILE *, cla_t *data);
 
-status_t export_data(cla_t cla, const user_t *users, size_t size);
 void clean_data(char **data);
 
+/*
 status_t export_data_as_csv(FILE *fo, const user_t *users, size_t size);
 status_t export_data_as_xml(FILE *fo, const user_t *users, size_t size);
+*/
 
-status_t destroy_data(char **data);
+status_t destroy_data(char **, size_t);
 status_t get_date(time_t *e, char **data);
 
 void clean_buffer(char *buf);
diff --git a/include/user.h b/include/user.h
@@ -3,31 +3,25 @@
 
 #include "status.h"
 
+#define OUT_FILE_DELIM    ","
+
 typedef unsigned long ulong;
 
 typedef struct {
     /* id: user id / c: user credits / d: user debits */
     ulong id, c, d;
-} ADT_user_t, *user_t;
-
-user_t user_find(const user_t *users, int id, size_t size);
-user_t user_dup(user_t src);
+} ADT_user_t;
 
 status_t user_create(ADT_user_t **);
 status_t user_set_data(ADT_user_t *, char **data);
 status_t user_add_amount(ADT_user_t *, long amount);
 
-int user_id_equal(const void *, const void *);
-
-void user_clean(user_t usr);
+int user_equals(const void *, const void *);
 
-status_t sort_users(user_t *users, size_t size, char *order);
-status_t destroy_users(user_t *users, size_t size);
-
-status_t user_printer(const void *, FILE *);
+status_t user_print_as_csv(const void *u, FILE *fp);
+status_t user_print_as_xml(const void *u, FILE *fp);
 
 int user_comparator(const void *, FILE *);
-
 int user_comparator_credits_minmax(const void *, const void *);
 int user_comparator_credits_maxmin(const void *, const void *);
 
diff --git a/include/vector.h b/include/vector.h
@@ -30,7 +30,7 @@ status_t ADT_Vector_destroy(ADT_Vector_t **);
 status_t ADT_Vector_load(ADT_Vector_t *, FILE *);
 
 status_t ADT_Vector_set(ADT_Vector_t **, void *, size_t);
-status_t ADT_Vector_print(const ADT_Vector_t *, FILE *);
+status_t ADT_Vector_print(const ADT_Vector_t *, FILE *, printer_t);
 status_t ADT_Vector_sort(ADT_Vector_t *, comparator_t);
 
 void *ADT_Vector_get_elem(const ADT_Vector_t *v, void *e);
diff --git a/source/cla.c b/source/cla.c
@@ -3,17 +3,20 @@
 const char *available_flags[] = { "-fmt", "-out", "-in", "-ti", "-tf" };
 const char *available_formats[] = { "csv", "xml" };
 
-status_t validate_arguments(int argc,  char **argv)
+status_t validate_arguments(int argc, char **argv, cla_t cla)
 {
     status_t st;
 
-    if(argv == NULL) return ERROR_NULL_POINTER;
+    if(argv == NULL || cla == NULL) return ERROR_NULL_POINTER;
     if((argc == NO_ARGS_ENTERED) || (argc != NORMAL_AMOUNT_ARGS))
         return ERROR_MISSING_ARGS;
 
     if((st = check_flags_position(argc, argv))) return st;
     if((st = check_flags_repeated(argc, argv))) return st;
 
+    /* Asigna a la estructura 'cla' los argumentos ingresados */
+    if((st = cla_setup(argc, argv, cla))) return st;
+
     return OK;
 }
 
@@ -60,23 +63,32 @@ status_t check_flags_repeated(int argc, char **argv)
     return OK;
 }
 
-status_t cla_setup(int argc, char **argv, cla_t *cla)
+status_t cla_setup(int argc, char **argv, cla_t cla)
 {
     char *endptr;
     size_t i;
+    FILE *fp;
     flags_t f;
 
     for(i = 1; i < argc; i += 2) {
         for(f = FLAG_FMT; f < FLAGS_MAX; f++) {
             if(!strcmp(available_flags[f], argv[i])) {
                 switch (f) {
-                    case FLAG_FMT: strcpy((*cla)->fmt, argv[i + 1]); break;
-                    case FLAG_OUT: strcpy((*cla)->fo, argv[i + 1]); break;
-                    case FLAG_IN: strcpy((*cla)->fi, argv[i + 1]); break;
-                    case FLAG_TI: (*cla)->ti = strtoul(argv[i + 1], &endptr, 10); 
+                    case FLAG_FMT: strcpy(cla->fmt, argv[i + 1]); break;
+                    case FLAG_OUT: if((fp = fopen(argv[i + 1], "wt")) == NULL)
+                                       return ERROR_OPENING_FILE;
+
+                                   cla->fo = fp; 
+                                   break;
+                    case FLAG_IN: if((fp = fopen(argv[i + 1], "rt")) == NULL)
+                                      return ERROR_OPENING_FILE;
+
+                                   cla->fi = fp; 
+                                   break;
+                    case FLAG_TI: cla->ti = strtoul(argv[i + 1], &endptr, 10); 
                                   if(*endptr != '\0') return ERROR_WRONG_TIME;
                                   break;
-                    case FLAG_TF: (*cla)->tf = strtoul(argv[i + 1], &endptr, 10); 
+                    case FLAG_TF: cla->tf = strtoul(argv[i + 1], &endptr, 10); 
                                   if(*endptr != '\0') return ERROR_WRONG_TIME;
                                   break;
                     default: return ERROR_FLAG_NOT_FOUND;
@@ -101,34 +113,18 @@ status_t cla_create(cla_t *cla)
         return ERROR_MEMORY;
     }
 
-    if(((*cla)->fo = calloc(sizeof(char), 100)) == NULL) {
-        free((*cla)->fmt);
-        free(cla);
-        cla = NULL;
-        return ERROR_MEMORY;
-    }
-
-    if(((*cla)->fi = calloc(sizeof(char), 100)) == NULL) {
-        free((*cla)->fo);
-        free((*cla)->fmt);
-        free(cla);
-        cla = NULL;
-        return ERROR_MEMORY;
-    }
-
     return OK;
 }
 
-status_t cla_destroy(cla_t *cla)
+status_t cla_destroy(cla_t cla)
 {
     if(cla == NULL) return ERROR_NULL_POINTER;
 
-    free((*cla)->fmt);
-    free((*cla)->fo);
-    free((*cla)->fi);
-    free(*cla);
+    fclose(cla->fo);
+    fclose(cla->fi);
 
-    *cla = NULL;
+    free(cla->fmt);
+    free(cla);
 
     return OK;
 }
diff --git a/source/io.c b/source/io.c
@@ -1,120 +1,5 @@
 #include "../include/io.h"
 
-
-/*
-//Lee los datos del archivo de entrada linea por linea mientras los procesa y asigna a un arreglo de usuarios
-status_t process_file(cla_t cla, user_t **users, size_t *size)
-{
-    FILE *fpi;
-    char *buffer, **data;
-    time_t epoch;
-    size_t alloc_size;
-    user_t user, user_found, *tmp;
-    status_t st;
-
-    *size = 0;
-    alloc_size = INIT_SIZE;
-    user = user_found = NULL;
-
-    if((fpi = fopen(cla->fi, "rt")) == NULL) {
-        *users = NULL;
-        return ERROR_OPENING_FILE;
-    }
-
-    if((data = (char **)malloc(sizeof(char *) * INPUT_FILE_FIELDS)) == NULL) {
-        fclose(fpi);
-        return ERROR_MEMORY;
-    }
-
-    if((buffer = calloc(sizeof(char), BUFFER_SIZE)) == NULL) {
-        destroy_data(data);
-        fclose(fpi);
-        return ERROR_MEMORY;
-    }
-
-    if(user_create(&user) != OK) {
-        free(buffer);
-        destroy_data(data);
-        fclose(fpi);
-    }
-
-    //En caso de haber algun error users no es liberado, se libera luego en main
-    if(((*users) = (user_t *)malloc(sizeof(user_t) * INIT_SIZE)) == NULL) {
-        free(buffer);
-        free(user);
-        destroy_data(data);
-        fclose(fpi);
-    }
-
-    //Lee los datos de el archivo de entrada linea por linea 
-    while(fgets(buffer, BUFFER_SIZE, fpi) != NULL) {
-    //    Extiende el arreglo de usuarios en caso de que haya poca memoria
-        if(*size == alloc_size) {
-            alloc_size *= GROWTH_FACTOR;
-            if((tmp = realloc((*users), alloc_size * sizeof(user_t))) == NULL) {
-                fclose(fpi);
-                free(buffer);
-                destroy_data(data);
-                return ERROR_MEMORY;
-            }
-            (*users) = tmp;
-        }
-
-    //    Divide el buffer en subarreglos segun un caracter delimitador
-        if((st = string_split(buffer, data, INPUT_FILE_DELIM)) != OK) {
-            fclose(fpi);
-            free(buffer);
-            destroy_data(data);
-            return st;
-        }
-
-    //    Asigna a 'user' id, creditos y debitos cargados en data
-        if((st = user_set_data(&user, data)) != OK) {
-            destroy_data(data);
-            free(buffer);
-            fclose(fpi);
-            return st;
-        }
-
-    //    Transforma la fecha leida a tiempo UNIX en segundos
-        if((st = get_date(&epoch, data)) != OK) {
-            destroy_data(data);
-            free(buffer);
-            fclose(fpi);
-            return st;
-        }
-
-    //    Comprueba que la fecha leida este dentro del rango de fechas ingresadas en CLA
-        if(epoch < cla->ti) continue;
-        else if(epoch > cla->tf) {
-            free(user);
-            destroy_data(data);
-            free(buffer);
-            fclose(fpi);
-            return OK;
-        }
-
-    //    Busca el numero de id en los usuarios ya ingresados, si no lo encuentra agrega un usuario nuevo al arreglo de usuarios
-        if((user_found = user_find(*users, user->id, *size)) != NULL) {
-            user_found->c += user->c;
-            user_found->d += user->d;
-        } else {
-            (*users)[(*size)++] = user_dup(user);
-        }
-
-        user_clean(user);
-        clean_data(data);
-        clean_buffer(buffer);
-    } // End while 
-
-    free(user);
-    destroy_data(data);
-    free(buffer);
-    fclose(fpi);
-    return OK;
-}
-*/
-
 status_t string_split(char *s, char **data, char *delim)
 {
     char *p, *tmp;
@@ -129,13 +14,13 @@ status_t string_split(char *s, char **data, char *delim)
     return OK;
 }
 
-status_t destroy_data(char **data)
+status_t destroy_data(char **data, size_t fields)
 {
     size_t i;
 
     if(data == NULL) return ERROR_NULL_POINTER;
 
-    for(i = 0; i < INPUT_FILE_FIELDS; i++) {
+    for(i = 0; i < fields; i++) {
         free(data[i]);
         data[i] = NULL;
     }
@@ -143,26 +28,7 @@ status_t destroy_data(char **data)
     free(data);
     return OK;
 }
-
-status_t export_data(cla_t cla, const user_t *users, size_t size)
-{
-    FILE *fo;
-
-    if(users == NULL) return ERROR_NULL_POINTER;
-
-    if((fo = fopen(cla->fo, "wt")) == NULL)
-        return ERROR_OPENING_FILE;
-
-    if(!strcmp(cla->fmt, "csv")) {
-        export_data_as_csv(fo, users, size);
-    } else if(!strcmp(cla->fmt, "xml")) {
-        export_data_as_xml(fo, users, size);
-    } else return ERROR_FORMAT_NOT_FOUND;
-
-    fclose(fo);
-    return OK;
-}
-
+/*
 status_t export_data_as_csv(FILE *fo, const user_t *users, size_t size)
 {
     size_t i;
@@ -197,7 +63,7 @@ status_t export_data_as_xml(FILE *fo, const user_t *users, size_t size)
     fprintf(fo, "%s\n", XML_ROOT_CLOSE);
     return OK;
 }
-
+*/
 void clean_buffer(char *buf)
 {
     size_t i;
@@ -244,4 +110,3 @@ status_t get_date(time_t *e, char **data)
 
     return OK;
 }
-
diff --git a/source/main.c b/source/main.c
@@ -1,13 +1,14 @@
 #include "../include/io.h"
 #include "../include/cla.h"
 #include "../include/user.h"
-#include "../include/sort.h"
 #include "../include/status.h"
 #include "../include/vector.h"
 
-#define BUFFER_INIT_SIZE    100
-#define INPUT_FILE_DELIM    ","
-#define INPUT_FILE_FIELDS    6    
+#define IN_FILE_MAX_LEN    100
+#define IN_FILE_DELIM    ","
+#define OUT_FILE_DELIM    ","
+#define IN_FILE_FIELDS    6
+#define IN_FILE_FIELDS_MAX_LEN    50
 
 int main (int argc, char *argv[])
 {
@@ -15,22 +16,19 @@ int main (int argc, char *argv[])
     cla_t cla;
     ADT_Vector_t *v;
     ADT_user_t *user, *user_tmp;
-    char *b, *endptr;
+    char buffer[IN_FILE_MAX_LEN];
     char **data;
-    size_t i, j;
-    FILE *fi;
+    char *endptr;
     long amount;
 
-    user = NULL;
-
-    /* Valida que los argumentos sean correctos */
-    if((st = validate_arguments(argc, argv)) != OK) {
+    /* Asigna memoria a cla */
+    if((st = cla_create(&cla)) != OK) {
         show_status(st);
         return st;
     }
 
-    /* Asigna memoria a cla */
-    if((st = cla_create(&cla)) != OK) {
+    /* Valida que los argumentos sean correctos */
+    if((st = validate_arguments(argc, argv, cla)) != OK) {
         show_status(st);
         return st;
     }
@@ -38,70 +36,27 @@ int main (int argc, char *argv[])
     /* Crea un vector */
     if((st = ADT_Vector_create(&v)) != OK) {
         show_status(st);
-        cla_destroy(&cla);
+        cla_destroy(cla);
         return st;
     }
 
-    if((st = ADT_Vector_set_printer(v, user_printer)) != OK) {
+    /* Setea el comparador a ADT_Vector */    
+    if((st = ADT_Vector_set_comparator(v, user_equals)) != OK) {
         show_status(st);
-        cla_destroy(&cla);
+        cla_destroy(cla);
         ADT_Vector_destroy(&v);
         return st;
     }
 
-    /* Asigna a la estructura 'cla' los argumentos ingresados */
-    if((st = cla_setup(argc, argv, &cla)) != OK) {
+    if((st = user_create(&user_tmp)) != OK) {
         show_status(st);
-        cla_destroy(&cla);
+        cla_destroy(cla);
         ADT_Vector_destroy(&v);
         return st;
     }
 
-
-    b = calloc(sizeof(char), BUFFER_INIT_SIZE);
-    data = malloc(sizeof(char *) * INPUT_FILE_FIELDS);
-
-    if(b == NULL || data == NULL) {
-        free(b);
-        show_status(ERROR_MEMORY);
-        cla_destroy(&cla);
-        ADT_Vector_destroy(&v);
-        return ERROR_MEMORY;
-    }
-
-    /* Asigna memoria cada puntero dentro de data */
-    for(i = 0; i < INPUT_FILE_FIELDS; i++) {
-        if((data[i] = calloc(sizeof(char), BUFFER_INIT_SIZE)) == NULL) {
-            show_status(ERROR_MEMORY);
-            for(j = 0; j < i; j++)
-                free(data[j]);
-
-            free(b);
-            cla_destroy(&cla);
-            ADT_Vector_destroy(&v);
-            return ERROR_MEMORY;
-        }
-    }
-        
-    /* Abre el archivo de entrada */
-    if((fi = fopen(cla->fi, "rt")) == NULL) {
-        show_status(ERROR_OPENING_FILE);
-        for(j = 0; j < INPUT_FILE_FIELDS; j++)
-            free(data[j]);
-
-        free(b);
-        cla_destroy(&cla);
-        ADT_Vector_destroy(&v);
-        return ERROR_OPENING_FILE;
-    }
-
-    ADT_Vector_set_comparator(v, user_id_equal);
-
-    user_tmp = NULL;
-    user_create(&user_tmp);
-
-    while(fgets(b, BUFFER_INIT_SIZE, fi)) {
-        string_split(b, data, INPUT_FILE_DELIM);
+    while(fgets(buffer, IN_FILE_MAX_LEN, cla->fi)) {
+        string_split(buffer, data, IN_FILE_DELIM);
         user_set_data(user_tmp, data);
 
         amount = strtol(data[POS_AMOUNT], &endptr, 10);
@@ -119,67 +74,24 @@ int main (int argc, char *argv[])
         }
     }
 
-    ADT_Vector_sort(v, user_comparator_credits_maxmin);
-
-    ADT_Vector_print(v, stdout);
+    if((st = ADT_Vector_sort(v, user_comparator_credits_maxmin)) != OK) {
+        show_status(st);
+        free(user_tmp);
+        cla_destroy(cla);
+        ADT_Vector_destroy(&v);
+        return st;
+    }
 
-    for(j = 0; j < INPUT_FILE_FIELDS; j++)
-        free(data[j]);
+    if((st = ADT_Vector_print(v, stdout, user_print_as_csv)) != OK) {
+        show_status(st);
+        free(user_tmp);
+        cla_destroy(cla);
+        ADT_Vector_destroy(&v);
+        return st;
+    }
 
-    free(data);
-    free(b);
     free(user_tmp);
-    fclose(fi);
-    cla_destroy(&cla);
+    cla_destroy(cla);
     ADT_Vector_destroy(&v);
     return OK;
 }
-
-
-
-
-
-
-/*
-
-// "ca" - creditos ascendentes | "cd" - creditos descendentes
-// "da" - debitos ascendentes  | "dd" - debitos descendentes
-#define SORTING_ORDER    "cd"
-#define PRINT_EXIT_SUCCESS_MSG
-
-
-
-#ifdef PRINT_EXIT_SUCCESS_MSG
-
-    // Imprime un mensaje para darle a conocer al usuario
-    // que todo se ejecuto correctamente
-    printf("\n%s\n%s%ld\n%s%ld\n", EXIT_SUCCESS_MSG, USERS_REGISTERED_MSG,\
-            size, PROCESED_LINES_MSG, cla->parsed_lines);
-
-#endif
-*/
-
-
-    /* Carga en users los usuarios desde el archivo de entrada */
-    /* if((st = process_file(cla, &users, &size)) != OK) { */
-    /*     show_status(st); */
-    /*     cla_destroy(&cla); */
-    /*     destroy_users(users, size); */
-    /*     return st; */
-    /* } */
-
-    /* Ordena los usuarios con orden SORTING_ORDER */
-    /* if((st = sort_users(users, size, SORTING_ORDER)) != OK) { */
-    /*     show_status(st); */
-    /*     cla_destroy(&cla); */
-    /*     destroy_users(users, size); */
-    /*     return st; */
-    /* } */
-
-    /* Imprime los datos cargados en users a un archivo de salida */
-    /* if((st = export_data(cla, users, size)) != OK) { */
-    /*     show_status(st); */
-    /*     cla_destroy(&cla); */
-    /*     destroy_users(users, size); */
-    /*     return st; */
-    /* } */
diff --git a/source/user.c b/source/user.c
@@ -12,13 +12,6 @@ status_t user_create(ADT_user_t **user)
     return OK;
 }
 
-void user_clean(user_t usr)
-{
-    usr->id = 0;
-    usr->c = 0;
-    usr->d = 0;
-}
-
 status_t user_set_data(ADT_user_t *user, char **data) 
 {
     char *endptr;
@@ -48,44 +41,32 @@ status_t user_add_amount(ADT_user_t *user, long amount)
     return OK;
 }
 
-ADT_user_t *user_dup(user_t src)
+int user_equals(const void *a, const void *b)
 {
-    ADT_user_t *dst = NULL;
+    ADT_user_t *A, *B;
 
-    user_create(&dst);
+    if(a == NULL || b == NULL) return ERROR_NULL_POINTER;
 
-    dst->id = src->id;
-    dst->c = src->c;
-    dst->d = src->d;
+    A = (ADT_user_t *)a;
+    B = (ADT_user_t *)b;
 
-    return dst;
-}
+    if(A->id == B->id) return 1;
 
-user_t user_find(const user_t *users, int id, size_t size)
-{
-    size_t i;
-    for(i = 0; i < size; i++) {
-        if(users[i]->id == id) {
-            return users[i];
-        }
-    }
-    return NULL;
+    return 0;
 }
 
-status_t destroy_users(user_t *users, size_t size)
+status_t user_print_as_csv(const void *u, FILE *fp)
 {
-    size_t i;
+    if(u == NULL || fp == NULL) return ERROR_NULL_POINTER;
 
-    if(users == NULL) return ERROR_NULL_POINTER;
+    ADT_user_t *user = (ADT_user_t *)u;
 
-    for(i = 0; i < size; i++)
-        free(users[i]);
+    fprintf(fp, "%ld%s%ld%s%ld\n", user->id, OUT_FILE_DELIM, user->c, OUT_FILE_DELIM, user->d);
 
-    free(users);
     return OK;
 }
 
-status_t user_printer(const void *u, FILE *fp)
+status_t user_print_as_xml(const void *u, FILE *fp)
 {
     if(u == NULL || fp == NULL) return ERROR_NULL_POINTER;
 
@@ -96,28 +77,14 @@ status_t user_printer(const void *u, FILE *fp)
     return OK;
 }
 
-int user_id_equal(const void *a, const void *b)
-{
-    ADT_user_t *A, *B;
-
-    if(a == NULL || b == NULL) return ERROR_NULL_POINTER;
-
-    A = (ADT_user_t *)a;
-    B = (ADT_user_t *)b;
-
-    if(A->id == B->id) return 1;
-
-    return 0;
-}
-
 int user_comparator_credits_minmax(const void *a, const void *b)
 {
-    user_t A, B;
+    ADT_user_t *A, *B;
 
     if(a == NULL || b == NULL) return ERROR_NULL_POINTER;
 
-    A = *(user_t *)a;
-    B = *(user_t *)b;
+    A = *(ADT_user_t **)a;
+    B = *(ADT_user_t **)b;
 
     if(A->c > B->c) return 1;
     else if(A->c == B->c) return 0;
@@ -126,12 +93,12 @@ int user_comparator_credits_minmax(const void *a, const void *b)
 
 int user_comparator_credits_maxmin(const void *a, const void *b)
 {
-    user_t A, B;
+    ADT_user_t *A, *B;
 
     if(a == NULL || b == NULL) return ERROR_NULL_POINTER;
 
-    A = *(user_t *)a;
-    B = *(user_t *)b;
+    A = *(ADT_user_t **)a;
+    B = *(ADT_user_t **)b;
 
     if(A->c < B->c) return 1;
     else if(A->c == B->c) return 0;
diff --git a/source/vector.c b/source/vector.c
@@ -74,8 +74,6 @@ status_t ADT_Vector_load(ADT_Vector_t *v, FILE *fi)
         if(*endptr != '\n') return ERROR_CORRUPT_DATA;
 
         ADT_Vector_add(&v, tmp);
-
-        ADT_Vector_print(v, stdout);
     }
 
     return OK;
@@ -134,14 +132,14 @@ void *ADT_Vector_get_elem(const ADT_Vector_t *v, void *e)
     return NULL;
 }
 
-status_t ADT_Vector_print(const ADT_Vector_t *v, FILE *fp)
+status_t ADT_Vector_print(const ADT_Vector_t *v, FILE *fp, printer_t pf)
 {
     size_t i;
 
     if(v == NULL) return ERROR_NULL_POINTER;
 
     for(i = 0; i < v->size; i++)
-        v->printer(v->a[i], fp);
+        (*pf)(v->a[i], fp);
 
     putchar('\n');
     return OK;