Как отмечено в комментариях от 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
заменит каждый разделитель в tmp
на нуль-символ в порядкечтобы токенизировать строку, теперь tmp
будет содержать:
tmp = "somevalue\0 othervalue\0"
При вызове getunused(tmp, SECOND_COLUMN)
(где SECOND_COLUMN
предположительно 2
), !--n
tests false
и NULL
возвращается.
Зачем токенизировать?
Редко вам потребуется токенизировать поля из файла .csv
(или в вашем случае a точка с запятой отдельный файл) Почему?В этом и заключается цель файла с разделенными значениями - поэтому вы можете прочитать файл как ввод, используя отформатированную функцию ввода для разделения полей, а не для разграничения на разделители.(что вы можете сделать - это просто не обязательно).В вашем случае, если формат файла .csv соответствует приведенному выше, вы можете полностью исключить getunused
и просто использовать sscanf
для разделения строк ввода, например,
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);
}
(примечание: как и в моем комментарии, вы должны включить модификатор field-width MAX_ARG_LENGTH-1
(число) как часть вашего format-спецификатора - как отредактировано вышепосле вашего последнего комментария)
Кроме того, если ваше второе значение заканчивается на '\n'
, тогда отбросьте ';'
из класса символов , например, %49[^\n]
подойдет для2-е значение.