9511_project01

project 1 for algorithms & programming I (9511) prof. Cardozo
Index Commits Files Refs README
commit a83d11b524462fa7f71e8fa5a08fa8f0bccad8b7
parent 3aa37419650314b80982f5624a4837feddbcfd66
Author: Martin J. Klöckner <64109770+klewer-martin@users.noreply.github.com>
Date:   Wed,  3 Feb 2021 17:05:06 -0300

Merge pull request #2 from klewer-martin/alpha

Pull request #2
Diffstat:
Marguments.c | 14+++++++++++---
Mdata.c | 9++++++---
Minput.csv | 2+-
Dinput2.csv | 10----------
Riso3166-1_numbers_and_countries.csv -> iso3166-1.csv | 0
Mload_country_codes.c | 6++++--
Mmacros.h | 22+++++++++++++++++-----
Mmain.c | 6++++--
Mmain.h | 5+++--
Doutput.csv | 0
Aoutput.txt | 36++++++++++++++++++++++++++++++++++++
Mreadlines.c | 98++++++++++++++++++++++++++++++++++++++++++++++++-------------------------------
Mreadlines.h | 13++++---------
Dtime_translator.c | 38--------------------------------------
Dtime_translator.h | 6------
15 files changed, 146 insertions(+), 119 deletions(-)
diff --git a/arguments.c b/arguments.c
@@ -19,22 +19,30 @@ status_t validate_arguments(int argc, char * argv[], char * src, char * dest)
 
     int i;
     status_t inputFile, outputFile;
-    inputFile = outputFile = FILE_NOT_FOUND;
+    inputFile = outputFile = IO_FILE_NOT_FOUND;
 
     for(i = 1; i < argc; i++) {
+//        Comprueba que el primer argumento sea INPUT_ARGUMENT ('-in');
         if(!strcmp(argv[i], INPUT_ARGUMENT)) {
             printf(INPUT_ARGUMENT_FOUND_MSG);
+
+//            Si el argumento que sigue es OUTPUT_ARGUMENT entonces hay un error
+//            en la invocacion de el programa;
             if(!strcmp(argv[i + 1], OUTPUT_ARGUMENT))
                 return ERROR_INVOCATING_PROGRAM;
 
+//            Si el primer argumento esta bien y el siguiente es una cadena entonces
+//            guarda en src la cadena e imprime dicha cadena;
             strcpy(src, argv[++i]);
             printf(INPUT_FILE_NAME_MSG"'%s'\n", src);
+
+//            Marca el archivo de entrada como encontrado;
             inputFile = OK;
         } else if(!strcmp(argv[i], OUTPUT_ARGUMENT)) {
             printf(OUTPUT_ARGUMENT_FOUND_MSG);
             if(!strcmp(argv[i + 1], INPUT_ARGUMENT))
-
                 return ERROR_INVOCATING_PROGRAM;
+
             strcpy(dest, argv[++i]);
             printf(OUTPUT_FILE_NAME_MSG"'%s'\n", argv[i]);
             outputFile = OK;
@@ -43,7 +51,7 @@ status_t validate_arguments(int argc, char * argv[], char * src, char * dest)
 
 //    Return error if it could get input or output file names;
     if((inputFile && outputFile) != OK)
-        return ERROR_INVOCATING_PROGRAM;
+        return IO_FILE_NOT_FOUND;
 
     return OK;
 }
diff --git a/data.c b/data.c
@@ -1,18 +1,21 @@
 #include "main.h"
 #include "macros.h"
 
+
+//    The switch below the order of the error must be in the same as "main.h" 
+//    status_t structure, in order to print the correct errors;
 void print_error(status_t error)
 {
     switch (error) {
+        case IO_FILE_NOT_FOUND: 
+            fprintf(stderr, MSG_IO_FILE_NOT_FOUND"\n");
+            break;
         case ERROR_INVOCATING_PROGRAM: 
             fprintf(stderr, MSG_ERROR_INVOCATING_PROGRAM"\n");
             break;
         case ERROR_NULL_POINTER:
             fprintf(stderr, MSG_ERROR_NULL_POINTER"\n");
             break;
-        case FILE_NOT_FOUND: 
-            fprintf(stderr, MSG_FILE_NOT_FOUND"\n");
-            break;
         case ERROR_LOADING_COUNTRY_CODES:
             fprintf(stderr, MSG_ERROR_LOADING_COUNTRY_CODES"\n");
             break;
diff --git a/input.csv b/input.csv
@@ -1,5 +1,5 @@
 PAIS, FECHA, INFECTADOS
-32,1577880000
+32,1577880000,2342
 32,1578657600,4923
 32,1579089600,9324
 170,1577880000,8234
diff --git a/input2.csv b/input2.csv
@@ -1,10 +0,0 @@
-PAIS, FECHA, INFECTADOS
-32,1577880000,2342
-32,1578657600,4923
-32,1579089600,9324
-170,1577880000,8234
-170,1578657600,9234
-170,1579089600,9423
-276,1577880000,8432
-276,1579089600,9129
-276,1579521600,4214 
diff --git a/iso3166-1_numbers_and_countries.csv b/iso3166-1.csv
diff --git a/load_country_codes.c b/load_country_codes.c
@@ -7,6 +7,7 @@
 #include "macros.h"
 #include "load_country_codes.h"
 
+
 status_t clean (char *buffer, size_t size)
 {
     size_t i;
@@ -61,8 +62,9 @@ status_t load_country_codes(char country_codes[COUNTRIES_NUMBER][ARRAYS_LENGTH])
         
     buff = malloc(INITIAL_SIZE);
     
-    if((fp = fopen(COUNTRY_CODES_FILE_NAME, "r")) == NULL)
-        return ERROR_NULL_POINTER;
+    if((fp = fopen(COUNTRY_CODES_FILE_NAME, "r")) == NULL) {
+        return ERROR_LOADING_COUNTRY_CODES;
+    }
 
 
     while(fgets(buff, INITIAL_SIZE, fp) != NULL) {
diff --git a/macros.h b/macros.h
@@ -19,17 +19,29 @@
                                         "\t$ ./main -out <output file -in <input file>\n"\
                                         "Read documentation to know more"
 
-#define MSG_FILE_NOT_FOUND "No se ha encontrado dicho archivo\n"
+#define MSG_IO_FILE_NOT_FOUND     "\nIO_FILE_NOT_FOUND\n"\
+                                "Un de los archivos de entrada o salida no se ha especificado"\
+
+#define MSG_ERROR_LOADING_COUNTRY_CODES "\nERROR_LOADING_COUNTRY_CODES\n"\
+                                        "Ha ocurrido un error al cargar los codigos de los paises.\n"\
+                                        "compruebe que el archivo \""COUNTRY_CODES_FILE_NAME"\" se encuentre\n"\
+                                        "disponible en el directorio de el programa ejecutado y que\n"\
+                                        "el nombre coincida con el de \"COUNTRY_CODES_FILE_NAME\" dentro\n"\
+                                        "de el archivo main.h\n"
 
-#define MSG_ERROR_LOADING_COUNTRY_CODES
 #define MSG_ERROR_PRINTING
-#define MSG_ERROR_READING_FILE
-#define MSG_ERROR_ALLOCATING_TIME
+
+#define MSG_ERROR_READING_FILE            "\nERROR_READING_FILE\n"\
+                                        "El archivo de entrada no pudo ser leido, compruebe que el nombre este\n"\
+                                        "escrito correctamente y la existencia de el mismo"
+
+#define MSG_ERROR_ALLOCATING_TIME        "\nstrftime(3): el formato especificado "
+
 #define MSG_ERROR_DATA_ON_FILE_MISSING    "\nERROR_DATA_ON_FILE_MISSING\n"\
                                         "En alguna linea de el archivo de entrada falta un dato,\n"\
                                         "compruebe que dicho archivo no esta corrupto y ejecute\n"\
                                         "el programa nuevamente"
 
-#define MSG_OK "Everything executed correctly\n"
+#define MSG_OK "\nEverything executed correctly.\n"
 
 #endif
diff --git a/main.c b/main.c
@@ -47,17 +47,19 @@ int main(int argc, char * argv[])
         return st;
     }
     
-
 //    Carga los codigos de error de los paises de acuerdo al standard iso3166 en el
 //    arreglo mencionado previamente 'country_codes', en caso de haber algun error 
 //    en el proceso devuelve dicho codigo e impreme por stderr un mensaje de error; 
-    if(load_country_codes(country_codes) != OK)
+    if((st = load_country_codes(country_codes)) != OK) {
+        print_error(st);
         return ERROR_LOADING_COUNTRY_CODES;    
+    }
 
     if((st = readlines(src, dest)) != OK) {
         print_error(st);
         return st;
     }    
 
+    printf(MSG_OK);
     return OK;
 }
diff --git a/main.h b/main.h
@@ -6,11 +6,11 @@
 #include <string.h>
 #include <time.h>
 
-#define COUNTRY_CODES_FILE_NAME "iso3166-1_numbers_and_countries.csv"
+#define COUNTRY_CODES_FILE_NAME "iso3166-1.csv"
 
 typedef enum {
     OK,
-    FILE_NOT_FOUND,
+    IO_FILE_NOT_FOUND,
     ERROR_INVOCATING_PROGRAM,
     ERROR_NULL_POINTER,
     ERROR_LOADING_COUNTRY_CODES,
@@ -20,4 +20,5 @@ typedef enum {
     ERROR_DATA_ON_FILE_MISSING    
 } status_t;
 
+
 #endif
diff --git a/output.csv b/output.csv
diff --git a/output.txt b/output.txt
@@ -0,0 +1,36 @@
+Pais: Argentina
+Fecha: 01 Jan 2020
+Infectados: 2342
+
+Pais: Argentina
+Fecha: 10 Jan 2020
+Infectados: 4923
+
+Pais: Argentina
+Fecha: 15 Jan 2020
+Infectados: 9324
+
+Pais: Colombia
+Fecha: 01 Jan 2020
+Infectados: 8234
+
+Pais: Colombia
+Fecha: 10 Jan 2020
+Infectados: 9234
+
+Pais: Colombia
+Fecha: 15 Jan 2020
+Infectados: 9423
+
+Pais: Germany
+Fecha: 01 Jan 2020
+Infectados: 8432
+
+Pais: Germany
+Fecha: 15 Jan 2020
+Infectados: 9129
+
+Pais: Germany
+Fecha: 20 Jan 2020
+Infectados: 4214
+
diff --git a/readlines.c b/readlines.c
@@ -2,49 +2,61 @@
 //    por linea, y los va imprimiendo en pantalla
 
 
-
 #include "readlines.h"
 
 #define COUNTRY_PROMPT "Pais"
 
+#define SIZE_OF_BUFF1    32
+#define SIZE_OF_BUFF2    32    
+
 const char date_print_format[] = "%d %b %Y";
 
 status_t readlines(char *src, char *dest)
 {
     size_t line, i, j;
+    status_t st;
+
+//    Puntero para el archivo de entrada y de salida respectivamente;    
+    FILE *fpi; 
+    FILE *fpo;
 
-//    Puntero para el archivo de entrada;    
-    FILE *fp;
 
-    char buff1[] = "                          ";
-    char buff2[] = "                          ";
+    char buff1[SIZE_OF_BUFF1];
+    char buff2[SIZE_OF_BUFF2];
+
+    clean_buffer(buff1, SIZE_OF_BUFF1);
+    clean_buffer(buff2, SIZE_OF_BUFF2);
 
 //    Esta variable es para saber de que tipo de dato estamos hablando, si es un
 //    codigo de pais, una fecha o el numero de infectados;
     data_t data;
 
-    char country_codes[COUNTRIES_NUMBER][ARRAYS_LENGTH];
-    load_country_codes(country_codes);
-
     unsigned long country;
     unsigned long date;
     unsigned long infected;
 
+//    Arreglo para almacenar los codigos de los paises segun el standard iso3166-1,
+    char country_codes[COUNTRIES_NUMBER][ARRAYS_LENGTH];
 
-// Abre el archivo de entrada en modo lectura si por algun motivo no se puede
-// abrir devuelve un codigo de error;
-    if((fp = fopen(src, "r")) == NULL)
+//    Carga los datos al arreglo mencionado previamente, en caso de haber algun
+//    error devuelve el codigo de dicho error;
+    if((st = load_country_codes(country_codes)) != OK) 
+        return st;
+    
+//    Abre el archivo de entrada en modo lectura si por algun motivo no se puede
+//    abrir devuelve un codigo de error;
+    if((fpi = fopen(src, "r")) == NULL)
             return ERROR_READING_FILE;
 
+    if((fpo = fopen(dest, "w")) == NULL)
+            return ERROR_READING_FILE;
 
 //    Lee de el archivo de entrada linea por linea y va guardando las 
 //    lineas en buff1 hasta que se terminen;
-    for(line = 0; fgets(buff1, sizeof(buff1), fp) != NULL; line++)
+    for(line = 0; fgets(buff1, sizeof(buff1), fpi) != NULL; line++)
     {
-
 //    Este 'if' es para evitar la primer linea que no contiene ningun tipo de dato;
         if(line != 0) {
-
 //            Recorre el buff1 separando los datos de acuerdo a si es el codigo de
 //            un pais, una fecha o el numero de infectados;
             for(i = 0, j = 0, data = PAIS; buff1[i] != '\0'; i++)
@@ -53,8 +65,7 @@ status_t readlines(char *src, char *dest)
 //                Si encuentra una coma cambia el tipo de dato;
                 if((buff1[i] == ','))
                 {
-
-//                    Se incrementa i para evitar que sea guardado en algun lado;
+//                    Saltea la coma;                    
                     i++;
 
 //                    De acuerdo al tipo de dato que se guardo hasta llegar a la
@@ -66,9 +77,9 @@ status_t readlines(char *src, char *dest)
                     {
                         case PAIS: country = atoi(buff2); break;
                         case DATE: date = atol(buff2); j++; break;
-                        case INFECTED: infected = atol(buff2); break;
                     }
 
+
 //                    Como encontro una coma entonces el tipo de dato cambia;
                     data++;
 
@@ -77,7 +88,7 @@ status_t readlines(char *src, char *dest)
                     j = 0;
 
 //                    Se limpia el buffer ya que se va a volver a utilizar;
-                    clean_buffer(buff2);
+                    clean_buffer(buff2, SIZE_OF_BUFF2);
 
 
 //                Si en lugar de una coma se encuentra un caracter de nueva line 
@@ -94,6 +105,8 @@ status_t readlines(char *src, char *dest)
 //                    Si esta todo bien entonces el dato vuelve a ser PAIS que es 
 //                    el primer dato de el archivo de entrada
                     data = PAIS;
+                    infected = atol(buff2);
+                    clean_buffer(buff2, SIZE_OF_BUFF2);
                 }
 
                 switch(data) 
@@ -101,63 +114,72 @@ status_t readlines(char *src, char *dest)
                     case PAIS: buff2[i] = buff1[i];    break;
                     case DATE: buff2[j] = buff1[i]; j++; break;
                     case INFECTED: buff2[j] = buff1[i]; j++; break;
-
                 }
             }
-//            print_country(country, country_codes);
-//            print_date(date);
-//            print_infected(infected);
+            fprintf_country(fpo, country, country_codes);
+            fprintf_date(fpo, date);
+            fprintf_infected(fpo, infected);
         }
     }
 
-    fclose(fp);
+    fclose(fpi);
+    fclose(fpo);
     return OK;
 }
 
 
 
-status_t print_country(size_t country_code, char country_codes[COUNTRIES_NUMBER][ARRAYS_LENGTH])
+status_t fprintf_country(FILE *dest, size_t country_code, char country_codes[COUNTRIES_NUMBER][ARRAYS_LENGTH])
 {
-    if(country_codes == NULL)
+    if((country_codes == NULL) || (dest == NULL))
         return ERROR_NULL_POINTER;
 
-    printf(COUNTRY_PROMPT": %s\n", country_codes[country_code]);
+    fprintf(dest, COUNTRY_PROMPT": %s\n", country_codes[country_code]);
     return OK;
 }
 
-status_t print_date(size_t date)
+status_t fprintf_date(FILE *dest, size_t date)
 {
     char time_c[TIME_MAX_DIGITS];
-    
-    time_translator(date, time_c, sizeof(time_c));
-    printf("Fecha: %s\n", time_c);
+    status_t st;
+
+    if(dest == NULL)
+        return ERROR_NULL_POINTER;
+
+    if((st = time_translator(date, time_c, sizeof(time_c))) != OK)
+        return st;
 
+    fprintf(dest, "Fecha: %s\n", time_c);
     return OK;
 }
 
-status_t print_infected(size_t infected)
+status_t fprintf_infected(FILE *dest, size_t infected)
 {
-    printf("Infectados: %lu\n\n", infected);
+    if(dest == NULL)
+        return ERROR_NULL_POINTER;
 
+    fprintf(dest, "Infectados: %lu\n\n", infected);
     return OK;
 }
 
-status_t clean_buffer(char *buffer)
+status_t clean_buffer(char *buffer, size_t size)
 {
     if(buffer == NULL)
         return ERROR_NULL_POINTER;
 
-    while(*buffer != '\0')
-    {
-        (*buffer) = ' ';
-        buffer++;
-    }
+    size_t i;
+    for(i = 0; i < size; i++)
+        buffer[i] = '\0';
+    
     return OK;
 }
 
 
 status_t time_translator(time_t unix_time, char *res, size_t size) 
 {
+    if(res == NULL)
+        return ERROR_NULL_POINTER;
+
     const char *format = date_print_format;
     struct tm *tmp = gmtime(&unix_time);
 
diff --git a/readlines.h b/readlines.h
@@ -4,14 +4,9 @@
 #include "main.h"
 #include "load_country_codes.h"
 
-#define INPUT_FILE_NAME "input.csv"
 #define INITIAL_SIZE 1000
 #define TIME_MAX_DIGITS 1000
 
-#define ARG "Argentina"
-#define COL "Colombia"
-#define GER "Germany"
-
 typedef enum {
     PAIS,
     DATE,
@@ -20,10 +15,10 @@ typedef enum {
 
 
 status_t readlines(char *src, char *dest);
-status_t print_date(size_t data);
-status_t print_infected(size_t data);
-status_t clean_buffer(char *buffer);
+status_t fprintf_date(FILE *dest, size_t data);
+status_t fprintf_infected(FILE *dest, size_t data);
+status_t clean_buffer(char *buffer, size_t size);
 status_t time_translator(time_t unix_time, char *res, size_t size); 
-status_t print_country(size_t country_code, char country_codes[COUNTRIES_NUMBER][ARRAYS_LENGTH]);
+status_t fprintf_country(FILE *dest, size_t country_code, char country_codes[COUNTRIES_NUMBER][ARRAYS_LENGTH]);
 
 #endif
diff --git a/time_translator.c b/time_translator.c
@@ -1,38 +0,0 @@
-#include <stdio.h>
-#include <time.h>
-#include <string.h>
-
-const char default_format[] = "%B %d %Y";
-
-typedef enum {
-    OK,
-    ERROR_NULL_POINTER
-} status_t;
-
-status_t date_translator(time_t unix_time, char *res, size_t size) 
-{
-    const char *format = default_format;
-    struct tm *tmp = gmtime(&unix_time);
-
-    if (strftime(res, size, format, tmp) == 0) {
-        (void) fprintf(stderr,  "strftime(3): cannot format supplied "
-                                "date/time into buffer of size %u "
-                                "using: '%s'\n",
-                                (unsigned int)sizeof(res), format);
-        return 1;
-    }
-    return 0;
-}
-
-int main (void) 
-{
-    char res[32];
-
-    time_t t;
-
-    t = 1577880000;
-
-    date_translator(t, res, sizeof(res));
-    puts(res);
-    return 0;
-}
diff --git a/time_translator.h b/time_translator.h
@@ -1,6 +0,0 @@
-#ifndef TIME_TRANSLATOR
-#define TIME_TRANSLATOR
-
-
-
-#endif