Когда я распечатываю результаты strtok (), я получаю числа, которые ищу, но я также печатаю (ноль) с ними:
Да, потому что вы зацикливаетесьпока не сделаешь.Рассмотрим:
while (token != NULL) {
token = strtok(NULL, ",");
printf("%s\n", token);
vc_vector_push_back(prices, &token);
}
Пока исходный токен не равен NULL, на каждой итерации вы читаете и затем печатаете следующий токен.Только тогда, после того, как вы уже напечатали его, вы возвращаетесь к циклу, чтобы проверить, является ли он нулевым.
Поскольку вам, кажется, требуется ровно второй токен каждой строки, бессмысленно выполнять цикл.Просто позвоните strtok()
дважды:
char* token = strtok(singleLine, ",\n");
if (token) {
token = strtok(NULL, ",\n");
if (token) {
printf("%s\n", token);
vc_vector_push_back(prices, &token); // but see below
} // else handle malformed data
} // else handle malformed data
Кроме того, пока я здесь, быстрый вопрос, это free(token)
;нужно в какой-то момент?Или нет, потому что malloc()
никогда не вызывался?
Нет, потому что, как вы говорите, память не была выделена.Но подумайте о последствиях.Память не выделяется, потому что token
указывает на локальный массив singleLine
, который вы токенизируете.Это означает:
- Когда вы читаете следующую строку в том же буфере, вы заменяете наведенные данные.
- Когда функция возвращается, время жизни этого массива заканчивается, рендеринглюбые указатели (in) на него недействительны.
Похоже, что vc_vector
копирует элементы в, но в вашем случае это может быть только копирование самих указателей, а не значений, на которые они указывают, так чтоне помогает вообще ни с одним из вышеперечисленного.Вместо этого, чтобы не повредить ваши данные и в конечном итоге иметь вектор, полный висячих указателей, вы должны делать динамически распределяемые копии строк токенов и сохранять указатели на этих в вашем векторе.
Если он у вас есть, то нестандартная, но распространенная функция strdup()
может сделать такие копии для вас.В противном случае комбинация strlen()
, malloc()
и strcpy()
будет выполнять ту же работу.Обратите внимание, что даже при отсутствии явного вызова функции распределения при использовании strdup()
в случае успеха получающаяся в результате дублирующаяся строка действительно выделяется динамически, и ее нужно освобождать, когда она больше не нужна.
Кроме того, когда я пытаюсь распечатать фактический вектор, они просто выводят мусор
Ну это , потому что вы храните указатели на массивы символов в вашем векторе, нозатем пытается интерпретировать их, как если бы они были указателями на int
.Форматы указателей, вероятно, совместимы, но данные, на которые они указывают, совершенно не совместимы.А тип int
даже не является подходящим типом, поскольку ваши данные не являются целочисленными (если только вы не можете преобразовать их в представление с фиксированной запятой).Возможно, вместо дублирования строк вы хотите использовать и разрешить копировать вектор, double
s:
double d = strtod(token, NULL); // note: as written, performs no error checking
vc_vector_push_back(prices, &d);
Это может потребовать изменения способа инициализации вектора.Затем вы напечатаете их как двойные числа, скажем:
for (double *dp = vc_vector_begin(prices);
dp != vc_vector_end(prices);
dp = vc_vector_next(prices, dp)) {
printf("%.2f; ", *dp);
}