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:
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