我正在将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;
}
任何帮助解决这个问题/指出我正确的方向来解决这个问题我将不胜感激!
答案 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'
,例如';'
将为第二个值执行。