i want use generic vector hold data line in csv file. meet problem. input is:
monsterid,name,hitpoints,attack,defence,attacktimes,gold,exp,special
the output become
field 0 monsteriname field 1 name field 2 hitpointattack field 3 attack field 4 defence field 5 attacktigold field 6 gold field 7 exp field 8 special
here parts of code relevant problem:
definition of vector
type:
typedef void (*vectorfreefunction)(void *element); typedef struct vector { void *elements; // array of elements int capacity; // allocated size of array int size; // number of elements in use size_t elemsize; // size of data type of element. vectorfreefunction freefunc; } vector;
csv.c
... vector *getfields(char *line) { int = 0; const char *token; vector *fields = vectoralloc(sizeof(char*), null); (token = strtok(line, ","); token && *token; token = strtok(null, ",\n"), i++) { vectorpush(fields, (const void*)token); } (int = 0; != fields->size; i++) { printf("field %d %s\n", i, (const char*)vectorat(fields, i)); } return fields; }
vector.c
vector *vectoralloc(size_t elemsize, vectorfreefunction freefunc) { vector *vector = malloc(sizeof(vector)); if (vector == null) { fatalerror("cannot allocate vector"); } vector->capacity = default_capacity; vector->size = 0; vector->elemsize = elemsize; vector->elements = malloc(elemsize * vector->capacity); if (vector->elements == null) { fatalerror("cannot allocate elements array of vector"); } vector->freefunc = freefunc; return vector; } void *vectorat(vector *vector, int position) { assert(position < vector->size && position >= 0); return ((char*)vector->elements + (position * vector->elemsize)); } void vectorpush(vector *vector, const void *element) { if (vector->size == vector->capacity) { _vectordoublecapacity(vector); } void *destaddr = (char*)vector->elements + vector->size * vector->elemsize; memcpy(destaddr, element, vector->elemsize); // add end of vector vector->size++; } void _vectordoublecapacity(vector *vector) { vector->capacity *= 2; vector->elements = realloc(vector->elements, vector->elemsize * vector->capacity); if (vector->elements == null) { fatalerror("resizing capacity of vector fails"); } }
the elements push onto vector
pointers array pointed line
argument getfields
. difficult keep track of lifespan of vector
elements way, should instead allocate copies of tokens strdup()
, pass free
vectorfreefunction
when creating vector
.
futhermore, vectorat
returns pointer vector element, char *
, way use print contents of vector
incorrect: should cast (char **)
, dereference it.
here corrected version:
vector *getfields(char *line) { int = 0; const char *token; vector *fields = vectoralloc(sizeof(char*), free); (token = strtok(line, ","); token && *token; token = strtok(null, ",\n"), i++) { vectorpush(fields, strdup(token)); } (int = 0; < fields->size; i++) { printf("field %d %s\n", i, *(char **)vectorat(fields, i)); } return fields; }
Comments
Post a Comment