Add base for csv-data-manipulation.
This commit is contained in:
parent
bb3bf1fe53
commit
e217d1b9fd
4 changed files with 194 additions and 6 deletions
14
Makefile
14
Makefile
|
@ -1,20 +1,22 @@
|
||||||
|
|
||||||
SRC = $(wildcard src/*.c)
|
SRC = $(wildcard src/*.c)
|
||||||
DEPS = $(wildcard deps/**/*.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__
|
# CFLAGS = -std=c99 -Ideps -Wall -Wno-unused-function -U__STRICT_ANSI__
|
||||||
BINS = exercice
|
CFLAGS = -ggdb -std=c99 -Ideps -Wall -Wno-unused-function -pedantic
|
||||||
|
|
||||||
|
|
||||||
all: $(BINS)
|
all: $(BINS)
|
||||||
|
echo "BINS=$(BINS)"
|
||||||
|
|
||||||
$(BINS): $(SRC) $(OBJS)
|
$(BINS): $(SRC) $(OBJS)
|
||||||
$(CC) $(CFLAGS) -o $@ src/$(@:.exe=).c $(OBJS) $(LDFLAGS)
|
$(CC) $(CFLAGS) -o $@ src/$@.c $(OBJS) $(LDFLAGS)
|
||||||
|
|
||||||
%.o: %.c
|
%.o: %.c
|
||||||
$(CC) $< -c -o $@ $(CFLAGS)
|
$(CC) $< -c -o $@ $(CFLAGS)
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
$(foreach c, $(BINS), rm $(c);)
|
$(foreach c, $(BINS), rm -f $(c);)
|
||||||
rm $(OBJS) src/*.o
|
rm -f $(OBJS)
|
||||||
|
|
BIN
exercice
BIN
exercice
Binary file not shown.
5
fixtures/csv-data-manipulation.csv
Normal file
5
fixtures/csv-data-manipulation.csv
Normal file
|
@ -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
|
|
181
src/csv-data-manipulation.c
Normal file
181
src/csv-data-manipulation.c
Normal file
|
@ -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 <stdio.h>
|
||||||
|
#include <stdlib.h> /* malloc...*/
|
||||||
|
#include <string.h> /* strtok...*/
|
||||||
|
#include <ctype.h>
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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_col<max_cols; cur_col++) {
|
||||||
|
for (cur_row=0; cur_row<max_rows; cur_row++) {
|
||||||
|
idx = cur_col + (cur_row * csv->cols);
|
||||||
|
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;
|
||||||
|
}
|
Loading…
Reference in a new issue