c - 为什么输出字符串以奇怪的方式连接?

标签 c string csv

我想使用通用 vector 来保存 csv 文件中一行的数据。但我遇到了一个问题。我的输入是:

MonsterID,Name,Hitpoints,Attack,Defence,AttackTimes,Gold,Exp,Special

输出变成

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 *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");
    }
}

最佳答案

您插入 Vector 的元素是指向 line 指向的数组的指针getfields 的参数。很难跟踪Vector的使用生命周期。以这种方式分配元素,您应该使用 strdup() 分配 token 的副本并通过 free作为VectorFreeFunction创建 Vector 时.

此外,vectorAt返回指向 vector 元素的指针,该元素本身是 char * ,使用它打印 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;
}

关于c - 为什么输出字符串以奇怪的方式连接?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38698041/

相关文章:

c - 多进程中的读写器 C

c - 如何在 Dev C++ 中使用像 ╔ ═ 和 ╗ 这样的字符作为字符串的一部分?

java - 在对话框打开时显示 toast ?

php - CSV 根据内容调整列大小

c: 在子进程中运行的 exec() 中捕获一个段错误

C 复杂的内存泄漏

Java 字符串常量池——创建的对象数

c# - 将 csv 中的长数字导入到 access 中

python - 如何使用 Python 清理大型格式错误的 CSV 文件

c - 为结构体中的灵活数组分配内存