2016-08-01 7 views
0

一般的なベクトルを使用して、csvファイルの行のデータを保持したいとします。しかし、私は問題に会う。私の入力は次のとおりです。なぜ出力文字列が奇妙な方法で連結されるのですか?

MonsterID、名前、ヒットポイント、攻撃、防御、AttackTimes、ゴールド、経験、特別

出力はここ

Field 0 would be MonsterIName 
Field 1 would be Name 
Field 2 would be HitpointAttack 
Field 3 would be Attack 
Field 4 would be Defence 
Field 5 would be AttackTiGold 
Field 6 would be Gold 
Field 7 would be Exp 
Field 8 would be Special 

になるには、コードの一部でありますこの問題に関連する:

Vectorタイプの定義:

typedef void (*VectorFreeFunction)(void *element); 

typedef struct Vector { 
    void *elements; // An array of elements 
    int capacity;  // The allocated size of the array 
    int size;   // The number of elements in use 
    size_t elemSize; // Size of the data type of the element. 
    VectorFreeFunction freeFunc; 
} Vector; 

csv.c

... 
Vector *getfields(char *line) { 
    int i = 0; 
    const char *token; 

    Vector *fields = vectorAlloc(sizeof(char*), NULL); 

    for (token = strtok(line, ","); 
     token && *token; 
     token = strtok(NULL, ",\n"), i++) 
    { 
     vectorPush(fields, (const void*)token); 
    } 

    for (int i = 0; i != fields->size; i++) { 
     printf("Field %d would be %s\n", i, (const char*)vectorAt(fields, i)); 
    } 

    return fields; 
} 

vector.cあなたはVectorにプッシュ

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 the 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 to 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 the capacity of vector fails"); 
    } 
} 
+2

あなたは[___MCVE___](http://stackoverflow.com/help/mcve)を作成する気? –

+1

これはあまりにも小さすぎます。 'ベクトル'の定義がありません。 –

+0

私は2つの異なるものに対してelemSizeを使用しません。しかし、私が8バイト以上の文字列に問題があるというあなたのコメントは啓発されています。私は今それを確認する必要があります。 –

答えて

1

要素は、配列にポインタがgetfieldsline引数によって指されています。このようにVector要素の寿命を追跡することは難しいので、代わりにstrdup()のトークンのコピーを割り当て、Vectorを作成するときはfreeVectorFreeFunctionとして渡す必要があります。自身がchar *あるベクトル要素へのポインタを返すvectorAt

Futhermore、あなたがVectorの内容を印刷するためにそれを使用する方法が間違っている:あなたは(char **)として、そのデリファレンスそれをキャストする必要があります。ここで

修正バージョンです:

Vector *getfields(char *line) { 
    int i = 0; 
    const char *token; 

    Vector *fields = vectorAlloc(sizeof(char*), free); 

    for (token = strtok(line, ","); 
     token && *token; 
     token = strtok(NULL, ",\n"), i++) { 
     vectorPush(fields, strdup(token)); 
    } 

    for (int i = 0; i < fields->size; i++) { 
     printf("Field %d would be %s\n", i, *(char **)vectorAt(fields, i)); 
    } 

    return fields; 
} 
関連する問題