diff --git a/Makefile b/Makefile index 71bb07e..0b427d1 100644 --- a/Makefile +++ b/Makefile @@ -1,20 +1,22 @@ SRC = $(wildcard src/*.c) DEPS = $(wildcard deps/**/*.c) -OBJS = $(DEPS:.c=.o) +OBJS = $(patsubst %.c,%.o,$(DEPS)) +BINS = $(notdir $(patsubst %.c,%,$(SRC))) -CFLAGS = -std=c99 -Ideps -Wall -Wno-unused-function -U__STRICT_ANSI__ -BINS = exercice +# CFLAGS = -std=c99 -Ideps -Wall -Wno-unused-function -U__STRICT_ANSI__ +CFLAGS = -ggdb -std=c99 -Ideps -Wall -Wno-unused-function -pedantic all: $(BINS) + echo "BINS=$(BINS)" $(BINS): $(SRC) $(OBJS) - $(CC) $(CFLAGS) -o $@ src/$(@:.exe=).c $(OBJS) $(LDFLAGS) + $(CC) $(CFLAGS) -o $@ src/$@.c $(OBJS) $(LDFLAGS) %.o: %.c $(CC) $< -c -o $@ $(CFLAGS) clean: - $(foreach c, $(BINS), rm $(c);) - rm $(OBJS) src/*.o + $(foreach c, $(BINS), rm -f $(c);) + rm -f $(OBJS) diff --git a/exercice b/exercice deleted file mode 100644 index 15b370d..0000000 Binary files a/exercice and /dev/null differ diff --git a/fixtures/csv-data-manipulation.csv b/fixtures/csv-data-manipulation.csv new file mode 100644 index 0000000..d30c12d --- /dev/null +++ b/fixtures/csv-data-manipulation.csv @@ -0,0 +1,5 @@ +C1,C2,C3,C4,C5 +1,5,9,13,17 +2,6,10,14,18 +3,7,11,15,19 +4,8,12,16,20 diff --git a/src/csv-data-manipulation.c b/src/csv-data-manipulation.c new file mode 100644 index 0000000..822b3a8 --- /dev/null +++ b/src/csv-data-manipulation.c @@ -0,0 +1,181 @@ + +#define TITLE "CSV data manipulation" +#define URL "http://rosettacode.org/wiki/CSV_data_manipulation" + +#define _GNU_SOURCE +#define bool int +#include +#include /* malloc...*/ +#include /* strtok...*/ +#include + + +/** + * How to read a CSV file ? + */ + + +typedef struct { + char delim; + unsigned int rows; + unsigned int cols; + char ** table; +} CSV; + +/* trim whitespaces from left & right of a string */ +int trim(char ** str) { + int trimmed; + int n; + int len; + + len = strlen(*str); + n = len - 1; + /* from right */ + while((n>=0) && isspace((*str)[n])) { + (*str)[n] = '\0'; + trimmed += 1; + n--; + } + + /* from left */ + n = 0; + while((n < len) && (isspace((*str)[0]))) { + (*str)[0] = '\0'; + *str = (*str)+1; + trimmed += 1; + n++; + } + return trimmed; +} + +CSV * csv_create() { + CSV * csv; + + csv = malloc(sizeof(CSV)); + csv->rows = 0; + csv->cols = 0; + csv->table = NULL; + + return csv; +} + +int csv_destroy(CSV * csv) { + free(csv); + return 0; +} + + +/* Resize CSV table + * - grow columns: on each row, add missing columns cells + * - grow rows: add now rows, with all columns count + * - reduce columns: remove columns from right + * - reduce lines: remove columns from the end + */ +int csv_resize(CSV * csv, unsigned int new_cols, unsigned int new_rows) { + char ** new_table; + unsigned int cur_col, + cur_row, + idx, + new_idx, + max_cols, + max_rows; + bool in_old, in_new; + + /* add missing column cells */ + new_table = malloc(sizeof(char *) * new_cols * new_rows); + + max_cols = (new_cols > csv->cols)? new_cols : csv->cols; + max_rows = (new_rows > csv->rows)? new_rows : csv->rows; + + for (cur_col=0; cur_colcols); + new_idx = cur_col + (cur_row * new_cols); + + in_old = (cur_col < csv->cols) && (cur_row < csv->rows); + in_new = (cur_col < new_cols) && (cur_row < new_rows); + + if (in_old && in_new) { + /* re-link data */ + new_table[new_idx] = csv->table[idx]; + } else if (in_old) { + /* destroy data */ + free(csv->table[idx]); + } else { + /* set to NULL */ + new_table[new_idx] = NULL; + } + } + } + /* on rows */ + free(csv->table); + csv->table = new_table; + return 0; +} + +/* , char delim='\t' */ +int csv_open(CSV * csv, char * filename) { + FILE * fp; + unsigned int m_rows; + unsigned int m_cols, cols; + char line[2048]; + char * lineptr; + char * token; + + + fp = fopen(filename, "r"); + if (fp == NULL) { exit(EXIT_FAILURE); } + + m_rows = 0; + m_cols = 0; + while(fgets(line, sizeof(line), fp) != NULL) { + /* printf("Got line: %s", line); */ + m_rows += 1; + cols = 0; + lineptr = line; + while ((token = strtok(lineptr, ",")) != NULL) { + lineptr = NULL; + trim(&token); + printf("%s\t|", token); + cols += 1; + if (cols > m_cols) { m_cols = cols; } + csv_resize(csv, m_cols, m_rows); + } + printf("\n"); + } + + fclose(fp); + csv->delim = '\t'; + csv->rows = m_rows; + csv->cols = m_cols; + return 0; +} + +int csv_save(CSV * csv, char * filename) { + return 0; +} + +int csv_set(CSV * csv, unsigned int col, unsigned int row, char * value) { + return 0; +} + +int main(int argc, char ** argv) { + CSV * csv; + + printf("%s\n%s\n\n",TITLE, URL); + + + csv = csv_create(); + csv_open(csv, "fixtures/csv-data-manipulation.csv"); + + csv_set(csv, 0, 0, "Column0"); + csv_set(csv, 1, 1, "100"); + csv_set(csv, 2, 2, "200"); + csv_set(csv, 3, 3, "300"); + csv_set(csv, 4, 4, "400"); + + csv_save(csv, "fixtures/csv-data-manupulation.out.csv"); + csv_destroy(csv); + + return 0; +}