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 bfe9c77690b29e0e96f42ac5e51d96bbeb452e8f
parent d725a953fc9d8a97b659405772a494fd069993af
Author: klewer-martin <martin.cachari@gmail.com>
Date:   Sat, 10 Jul 2021 16:49:16 -0300

Update: improved input/output module, now write data to a random access binary file to avoid excessive usage of RAM

Diffstat:
Mexamples/input_gen.py | 6+++---
Minclude/io.h | 5++++-
Msource/io.c | 20++++++++++++++------
Msource/main.c | 12++++++++++--
4 files changed, 31 insertions(+), 12 deletions(-)
diff --git a/examples/input_gen.py b/examples/input_gen.py
@@ -2,13 +2,13 @@ from string import digits
 from time import strftime, gmtime
 from random import randint, choice
 
-LINES = 2000000
+LINES = 2000
 
 # OUTPUT:
 #     ID_TRANSACCION, ID_USUARIO, FECHA, MONTO, NUMERO DE TRAJETA, DESCRIPCION
 #     123412,1,05/11/2011 10:00:00,-10,4916288217067475, Compra supermercado
 
-descs = [ "Compras supermercado", "Pago tarjeta", "Compras libreria", "Pago Mecanico", "Pago Dentista", "Compras farmacia", "Ventas online", "Extraccion cajero" ]
+descs = [ "Compras supermercado", "Pago tarjeta", "Compras libreria", "Pago Mecanico", "Pago Dentista", "Pago Servicios online", "Compras Ferreteria",  "Compras Accesorios Informatica", "Compras farmacia", "Ventas online", "Extraccion cajero" ]
 
 def card_number_generator():
     return ''.join(choice(digits) for i in range(1, 16))
@@ -28,7 +28,7 @@ def generate_file(max_lines):
         j = randint(1, len(descs) - 1)
         desc = descs[j] 
 
-        if j > 5:   amount = randint(amount_base, amount_max)
+        if j > 8:   amount = randint(amount_base, amount_max)
         else:   amount = randint(-amount_max, -amount_base)
 
         print(id_transaction,id_user,date,amount,card_nr,desc, sep=',')
diff --git a/include/io.h b/include/io.h
@@ -19,9 +19,12 @@ typedef enum {
     POS_DESC
 } csv_pos_t;
 
-status_t output_gen(cla_t cla);
+status_t tmp_gen(cla_t cla);
 status_t set_data(user_t *user, char **data);
+status_t tmp_sort(FILE *tmp);
 
 status_t split(char *s, char **data);
 
+status_t export_data(cla_t cla, FILE *bfp);
+
 #endif
diff --git a/source/io.c b/source/io.c
@@ -1,16 +1,18 @@
 #include "../include/io.h"
 
 void print_user(user_t user);
+void print_tmp_file(FILE *bfp, user_t user);
 
-status_t output_gen(cla_t cla)
+status_t tmp_gen(cla_t cla)
 {
-    FILE *fpi, *fpo;
+    FILE *fpi, *fpo, *bfp;
     char *buffer, **data;
     user_t user;
     status_t st;
 
     if((fpi = fopen(cla->fi, "rt")) == NULL) return ERROR_OPENING_FILE;
     if((fpo = fopen(cla->fo, "wt")) == NULL) return ERROR_OPENING_FILE;
+    if((bfp = fopen("tmp.bin", "wb")) == NULL) return ERROR_OPENING_FILE;
 
     data = (char **)malloc(sizeof(char *) * INPUT_FILE_FIELDS);
     for(size_t i = 0; i < INPUT_FILE_FIELDS; i++)
@@ -18,25 +20,26 @@ status_t output_gen(cla_t cla)
 
     buffer = calloc(sizeof(char), BUFFER_SIZE);
 
+    /* Lee los datos de el archivo de entrada y los imprime en un archivo binario temporal */
     while(fgets(buffer, BUFFER_SIZE, fpi) != NULL) {
         if((st = split(buffer, data))) return st;
         if((st = set_data(&user, data))) return st;
+        print_tmp_file(bfp, user);
         print_user(user);
     }
 
+    fclose(fpi);
+    fclose(fpo);
+    fclose(bfp);
     return OK;
 }
 
 status_t set_data(user_t *user, char **data) 
 {
     int amount;
-    status_t st;
 
     (*user) = (user_t)malloc(sizeof(user_t));
 
-    /* size_t fields = 0; */
-    /* for(p = buf; (data[fields++] = strtok(p, ",")); p = NULL); */
-
     (*user)->id = strtol(data[POS_USER_ID], NULL, 10);
 
     amount = strtol(data[POS_AMOUNT], NULL, 10);
@@ -60,3 +63,8 @@ void print_user(user_t user)
 {
     printf("ID: %5d | CREDITS: %5d | DEBITS: %5d\n", user->id, user->credit, user->debt);
 }
+
+void print_tmp_file(FILE *bfp, user_t user)
+{
+    fwrite(user, 1, sizeof(ADT_user_t), bfp);
+}
diff --git a/source/main.c b/source/main.c
@@ -7,6 +7,7 @@
 int main (int argc, char *argv[])
 {
     status_t st;
+    FILE *tmp_file;
     cla_t cla;
 
     if((st = validate_arguments(argc, argv)) != OK) {
@@ -14,13 +15,20 @@ int main (int argc, char *argv[])
         return st;
     }
 
-    if((st = setup(argc, argv, &cla))) {
+    if((st = setup(argc, argv, &cla)) != OK) {
         show_status(st);
         return st;
     }
     /* En este punto ya tengo todos los datos que necesito, el nombre de los archivos de entrada, el tiempo inicial y final, y el formato de el archivo de salida */
 
-    if((st = output_gen(cla))) {
+    /* Genera un archivo binario temporal con los datos parseados ordenado y listo para ser impresos */
+    if((st = tmp_gen(cla, tmp_file)) != OK) {
+        show_status(st);
+        return st;
+    }
+
+    /* Exporta el archivo temporal a un archivo de texto con formato de acuerdo a la flag recibida como argumento */
+    if((st = export_data(cla, tmp_file)) != OK) {
         show_status(st);
         return st;
     }