读取简单CSV文件时出现Seg Fault - C.

时间:2018-05-21 05:49:20

标签: c csv memory segmentation-fault

我正在将2列圆柱形csv文件读入结构数组:

struct unused_s{
    char col1[MAX_ARG_LENGTH];
    char col2[MAX_ARG_LENGTH];
};

struct unused_s unused[MAX_USEABLE];

但我得到了一个" Segmentation fault: 11"执行期间。我已经尽力通过重新分配内存来自己调试,但我担心我的能力无法完成任务。但是,我已经确定错误发生在这部分代码的某处:

void readCSV(FILE *file){
    int i = 0;

    char line[MAX_LINE_LENGTH];

    while (fgets(line, 1024, file))
    {
        char* tmp = strdup(line);
        strcpy(unused[i].col1, getunused(tmp, FIRST_COLUMN));
        strcpy(unused[i].col2, getunused(tmp, SECOND_COLUMN));
        free(tmp);
        i++;
    }

    fclose(file);

}

const char* getunused(char* line, int n)
{
    const char* tok;
    for (tok = strtok(line, ";");
            tok && *tok;
            tok = strtok(NULL, ";\n"))
    {
        if (!--n)
            return tok;
    }
    return NULL;
}

任何帮助解决这个问题/指出我正确的方向来解决这个问题我将不胜感激!

1 个答案:

答案 0 :(得分:1)

正如John3136的评论中所述,您将从NULL返回getunused(),例如

const char* getunused(char* line, int n)
{
    const char* tok;
    for (tok = strtok(line, ";");
            tok && *tok;
            tok = strtok(NULL, ";\n"))
    {
        if (!--n)
            return tok;
    }
    return NULL;
}

在您致电strtok时,您的输入文件似乎会导致tmp类似于:

tmp = "somevalue; othervalue\n"

第一次致电getunused()后,strtok将用{em> nul-character 替换tmp中的每个分隔符,以便对字符串进行标记, tmp现在将包含:

tmp = "somevalue\0 othervalue\0"

当您致电getunused(tmp, SECOND_COLUMN)时(其中SECOND_COLUMN可能是2),!--n测试false并返回NULL

为何选择令牌?

您很少需要<{1}}文件中的标记化字段(或者在您的情况下是分号分隔文件)为什么?这是分隔值文件的整个目的 - 因此您可以使用格式化的输入函数将文件作为输入读取,以分隔字段而不是对分隔符进行标记。 (你可以做 - 它通常不是必需的)。在您的情况下,如果您的.csv文件格式如上所述,那么您可以完全消除.csv并简单地使用getunused来分隔输入字符串,例如。

sscanf

注意:,如在我的评论中,您应该将{em>字段宽度修饰符void readCSV (FILE *file) { int i = 0; while (fgets(line, 1024, file)) if (sscanf (line "%49[^;] %49[^;\n]", unused[i].col1, unused[i].col2) == 2) i++; fclose(file); } (数字)包含在中格式说明符 - 在上次评论后编辑,如上所述)

此外,如果您的第二个值由MAX_ARG_LENGTH-1终止,则从字符类中删除'\n',例如';'将为第二个值执行。