Advertisement
Guest User

Untitled

a guest
Oct 20th, 2017
102
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 9.47 KB | None | 0 0
  1. #define _POSIX_C_SOURCE 200809L //getline
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <stdbool.h>
  5. #include <string.h>
  6. #include "strutil.h"
  7. #include "pila.h"
  8. #include "lista.h"
  9.  
  10. //Definicion de los tipos de dato
  11. typedef struct pago {
  12.     size_t id;
  13.     char* codigo;
  14.     double monto;
  15. } pago_t;
  16.  
  17. typedef struct usuario {
  18.     size_t id;
  19.     char* coordenadas;
  20.     double saldo;
  21. } usuario_t;
  22.  
  23. //Funciones auxiliares
  24.  
  25. int contar_lineas(char* nombre_archivo){
  26.  
  27.     //Utilidad de getline
  28.     char* linea = NULL;
  29.     size_t capacidad = 0;
  30.     ssize_t leidos;
  31.  
  32.     FILE* f_cuentas_usuarios = fopen(nombre_archivo,"r"); //Validar que se pudo abrir!!!
  33.     int numero_lineas = 0;
  34.     while((leidos = getline(&linea,&capacidad,f_cuentas_usuarios)) > 0){
  35.         numero_lineas++;
  36.     }
  37.     free(linea);
  38.     fclose(f_cuentas_usuarios);
  39.     return numero_lineas;
  40. }
  41.  
  42. int contar_parametros_leidos(char** leidos_stdin){
  43.     int i = 0;
  44.     while(leidos_stdin[i] != NULL){
  45.         i++;
  46.     }
  47.     return i;
  48. }
  49.  
  50. void borrar_salto_de_linea(char* str){
  51.     size_t largo_str = strlen(str);
  52.     str[largo_str] = '\0';
  53. }
  54.  
  55. //Funciones con usuarios & pagos
  56.  
  57. usuario_t* cargar_usuario(char* id_usuario, char* saldo, char* coordenadas){
  58.     usuario_t* usuario = malloc(sizeof(usuario_t));
  59.  
  60.     usuario->id = (size_t)atoi(id_usuario);
  61.     usuario->saldo = (double)atof(saldo);
  62.  
  63.     borrar_salto_de_linea(coordenadas);
  64.     usuario->coordenadas = coordenadas;
  65.     return usuario;
  66. }
  67.  
  68. usuario_t** cargar_usuarios_a_vector(char* nombre_archivo, size_t* cantidad_usuarios){
  69.     int numero_lineas_archivo = contar_lineas(nombre_archivo);
  70.  
  71.     usuario_t** vector_usuarios = malloc(sizeof(usuario_t) * (numero_lineas_archivo + 1));
  72.     if(!vector_usuarios){
  73.         return NULL;
  74.     }
  75.  
  76.     FILE* f_cuentas_usuarios = fopen(nombre_archivo,"r"); //Validar que se pueda abrir
  77.  
  78.     //Utilidad de getline
  79.     char* linea = NULL;
  80.     size_t capacidad = 0;
  81.  
  82.     size_t i = 0;
  83.     for(i = 0; i < numero_lineas_archivo; i++){
  84.         getline(&linea,&capacidad,f_cuentas_usuarios);
  85.         char** linea_parseada = split(linea, ',');
  86.  
  87.         vector_usuarios[i] = cargar_usuario(linea_parseada[0], linea_parseada[1], linea_parseada[2]);
  88.     }
  89.     *cantidad_usuarios = numero_lineas_archivo;
  90.    
  91.     //Pongo el ultimo como NULL para poder iterar sobre el array
  92.     vector_usuarios[numero_lineas_archivo] = NULL;
  93.     return vector_usuarios;
  94. }
  95.  
  96. usuario_t* buscar_usuario(size_t id_usuario, usuario_t** vector_usuarios, size_t cantidad_usuarios){
  97.     if(id_usuario >= cantidad_usuarios){
  98.         return NULL;
  99.     }
  100.     usuario_t* usuario_buscado = vector_usuarios[id_usuario];  
  101.     return usuario_buscado;
  102. }
  103.  
  104. pago_t* cargar_pago(char* id_pago, char* monto, char* codigo){
  105.     pago_t* pago = malloc(sizeof(pago_t));
  106.  
  107.     pago->id = (size_t)atoi(id_pago);
  108.     pago->monto = (double)atof(monto);
  109.  
  110.     borrar_salto_de_linea(codigo);
  111.     pago->codigo = codigo;
  112.     return pago;
  113. }
  114.  
  115. //Funciones de codigo de pila
  116.  
  117. bool validar_usuario(pila_t* pila_codigo, usuario_t** vector_usuarios, size_t cantidad_usuarios){
  118.     char* coordenadas = pila_desapilar(pila_codigo);
  119.     size_t id = (size_t)atoi(pila_desapilar(pila_codigo));
  120.  
  121.     //buscar_usuario devuelve NULL si no lo encuentra
  122.     usuario_t* usuario = buscar_usuario(id, vector_usuarios, cantidad_usuarios);
  123.  
  124.     //Controla que el ID exista
  125.     if(!usuario){
  126.         return false;
  127.     } else {
  128.         //Controla que el ID coincida con las coordenadas
  129.         if(strcmp(usuario->coordenadas,coordenadas) != 0){
  130.             return true;
  131.         } else
  132.             return false;
  133.     }
  134. }
  135.  
  136. bool validar_pago(pila_t* pila_codigo, usuario_t** vector_usuarios, size_t cantidad_usuarios){
  137.     double monto = atof(pila_desapilar(pila_codigo));;
  138.     size_t id_usuario = (size_t)atoi(pila_desapilar(pila_codigo));
  139.  
  140.     usuario_t* usuario = buscar_usuario(id_usuario, vector_usuarios, cantidad_usuarios);
  141.  
  142.     //Valida que el usuario tenga saldo suficiente para el pago
  143.     if(usuario->saldo >= monto){
  144.         return true;
  145.     }
  146.     return false;
  147. }
  148.  
  149. bool pagar(pila_t* pila_codigo, usuario_t** vector_usuarios, size_t cantidad_usuarios){
  150.  
  151.     size_t id_usuario_que_paga = (size_t)atoi(pila_desapilar(pila_codigo));
  152.     size_t id_usuario_que_recibe = (size_t)atoi(pila_desapilar(pila_codigo));
  153.     double monto = (double)atof(pila_desapilar(pila_codigo));
  154.  
  155.     usuario_t* usuario_que_paga = buscar_usuario(id_usuario_que_paga, vector_usuarios, cantidad_usuarios);
  156.     usuario_t* usuario_que_recibe = buscar_usuario(id_usuario_que_recibe, vector_usuarios, cantidad_usuarios);  
  157.  
  158.     //Modifica los pagos
  159.     usuario_que_paga->saldo = usuario_que_paga->saldo - monto;
  160.     usuario_que_recibe->saldo = usuario_que_recibe->saldo + monto;
  161.     return true;
  162. }
  163.  
  164. //Funciones de linea de comando (Usuario)
  165.  
  166. int agregar_pago(pago_t* pago, lista_t* cola_de_pagos){
  167.     if(lista_esta_vacia(cola_de_pagos)){
  168.         lista_insertar_primero(cola_de_pagos, pago);
  169.     } else {
  170.         lista_insertar_ultimo(cola_de_pagos, pago);
  171.     }
  172.     return 0;
  173. }
  174.  
  175. int pagos_pendientes(lista_t* cola_de_pagos){
  176.     pago_t* pago_aux;
  177.     lista_iter_t* iter = lista_iter_crear(cola_de_pagos);
  178.     double monto_total = 0;
  179.  
  180.     while(!lista_iter_al_final(iter)){
  181.         pago_aux = lista_iter_ver_actual(iter);
  182.         lista_iter_avanzar(iter);
  183.         monto_total = monto_total + pago_aux->monto;
  184.     }
  185.     fprintf(stdout, "%lu, %.3f\n", lista_largo(cola_de_pagos), monto_total);
  186.     lista_iter_destruir(iter);
  187.     return 0;
  188. }
  189.  
  190. int procesar(lista_t* cola_de_pagos, usuario_t** vector_usuarios, size_t cantidad_usuarios){
  191.     pila_t* pila_codigo = pila_crear(); //Manejar error no se puede crear pila
  192.    
  193.     //obtengo el pago
  194.     pago_t* pago_procesar = lista_borrar_primero(cola_de_pagos); //Manejar caso lista este vacia
  195.  
  196.     //printf("%s",pago_procesar->codigo);
  197.     char** codigo_parseado = split(pago_procesar->codigo, ';');
  198.    
  199.     size_t i = 0;
  200.     while(codigo_parseado[i] != NULL){
  201.         if(strcmp("validar_usuario",codigo_parseado[i]) == 0){
  202.             bool ok = validar_usuario(pila_codigo, vector_usuarios, cantidad_usuarios);
  203.             if(!ok){
  204.                 fprintf(stderr,"Error en pago %zu\n",pago_procesar->id);
  205.             }
  206.         }
  207.         if(strcmp("validar_pago",codigo_parseado[i]) == 0){
  208.             bool ok = validar_pago(pila_codigo, vector_usuarios, cantidad_usuarios);
  209.             if(!ok){
  210.                 fprintf(stderr,"Error en pago %zu\n",pago_procesar->id);
  211.             }
  212.         }
  213.         if(strcmp("pagar",codigo_parseado[i]) == 0){
  214.             pagar(pila_codigo, vector_usuarios, cantidad_usuarios);
  215.         }
  216.         pila_apilar(pila_codigo, codigo_parseado[i]);
  217.         i++;
  218.     }
  219.     pila_destruir(pila_codigo);
  220.     return 0;
  221. }
  222.  
  223. int guardar_cuentas(char* nombre_archivo, usuario_t** vector_usuarios){
  224.  
  225.     FILE* f_cuentas_usuarios = fopen(nombre_archivo,"w"); //Validar que se pueda abrir
  226.  
  227.     size_t i = 0;
  228.     while(vector_usuarios[i] != NULL){
  229.         fprintf(f_cuentas_usuarios, "%zu,%.3f,%s",vector_usuarios[i]->id, vector_usuarios[i]->saldo, vector_usuarios[i]->coordenadas);
  230.         i++;
  231.     }
  232.     fclose(f_cuentas_usuarios);
  233.     return 0;
  234. }
  235.  
  236. //Interfaz
  237.  
  238. void interfaz(lista_t* cola_de_pagos, usuario_t** vector_usuarios, size_t cantidad_usuarios){
  239.  
  240.     //Utilidad getline
  241.     char* linea = NULL;
  242.     size_t capacidad = 0;
  243.     ssize_t leidos;
  244.  
  245.     while((leidos = getline(&linea,&capacidad,stdin)) > 0){
  246.  
  247.         //Boro el ultimo '\n'
  248.         linea[leidos - 1] = '\0';
  249.         char** leidos_stdin = split(linea, ' ');
  250.  
  251.         if(strcmp("agregar_pago",leidos_stdin[0]) == 0){
  252.             int parametros_leidos = contar_parametros_leidos(leidos_stdin);
  253.             if(parametros_leidos != 4){
  254.                 fprintf(stderr,"Error en comando agregar_pago\n");
  255.                 return;
  256.             }
  257.             pago_t* pago = cargar_pago(leidos_stdin[1], leidos_stdin[2], leidos_stdin[3]);
  258.             agregar_pago(pago, cola_de_pagos);
  259.             fprintf(stdout, "OK \n");
  260.         }
  261.  
  262.         if(strcmp("pagos_pendientes",leidos_stdin[0]) == 0){
  263.             int parametros_leidos = contar_parametros_leidos(leidos_stdin);
  264.             if(parametros_leidos != 1){
  265.                 fprintf(stderr,"Error en comando pagos_pendientes\n");
  266.                 return;
  267.             }
  268.             pagos_pendientes(cola_de_pagos);
  269.             fprintf(stdout, "OK \n");
  270.         }
  271.  
  272.         if(strcmp("procesar",leidos_stdin[0]) == 0){
  273.             int parametros_leidos = contar_parametros_leidos(leidos_stdin);
  274.             if(parametros_leidos != 2){
  275.                 fprintf(stderr,"Error en comando procesar\n");
  276.                 return;
  277.             }
  278.  
  279.             size_t numero_procesar = (size_t)atoi(leidos_stdin[1]);
  280.             size_t i = 0;
  281.             while(i < numero_procesar || !lista_esta_vacia(cola_de_pagos)){
  282.                 procesar(cola_de_pagos, vector_usuarios, cantidad_usuarios);
  283.                 i++;
  284.             }
  285.             fprintf(stdout, "OK \n");
  286.         }
  287.  
  288.         if(strcmp("guardar_cuentas",leidos_stdin[0]) == 0){
  289.             int parametros_leidos = contar_parametros_leidos(leidos_stdin);
  290.             if(parametros_leidos != 2){
  291.                 fprintf(stderr,"Error en comando guardar_cuentas\n");
  292.                 return;
  293.             }
  294.  
  295.             char* nombre_archivo = leidos_stdin[1];
  296.             borrar_salto_de_linea(nombre_archivo);
  297.             guardar_cuentas(nombre_archivo, vector_usuarios);
  298.             fprintf(stdout, "OK \n");
  299.         }      
  300.    
  301.         if(strcmp("finalizar", leidos_stdin[0]) == 0){
  302.             int parametros_leidos = contar_parametros_leidos(leidos_stdin);
  303.             if(parametros_leidos != 1){
  304.                 fprintf(stderr,"Error en comando finalizar\n");
  305.                 return;
  306.             }
  307.             lista_destruir(cola_de_pagos, NULL);
  308.             free_strv(leidos_stdin);
  309.             fprintf(stdout, "OK \n");
  310.             return;
  311.         }
  312.     }
  313. }
  314.  
  315. //Main
  316.  
  317. int main(int argc, char *argv[]){
  318.  
  319.     //Borrar esto, es para probar
  320.     printf("Bienvenido a Wachencoin Service LTDA\n");
  321.  
  322.     //Creo la cola de pagos
  323.     lista_t* cola_de_pagos = lista_crear(); //Manejar error lista
  324.  
  325.     //Creo un vector de usuarios
  326.     size_t cantidad_usuarios;
  327.     usuario_t** vector_usuarios = cargar_usuarios_a_vector(argv[1], &cantidad_usuarios);
  328.  
  329.     //Llevo el usuario a la interfaz
  330.     interfaz(cola_de_pagos, vector_usuarios, cantidad_usuarios);
  331.  
  332.     return 0;
  333. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement