c - Why the output strings concatenate in a weird way? -


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