Это не ясно из опубликованного кода, но я предполагаю, что строка
Component *c = newComponent(cl);
будет 1) Создать новый элемент Компонента и 2) Вставить его в список cl
Так когда вы делаете это перед вызовом fscanf
, элемент уже вставлен **, даже если fscanf
не удается. Следовательно, вы получите «пустой» элемент в списке (он же фантомный элемент).
Чтобы избежать необходимости перемещать строку: Component *c = newComponent(cl);
, чтобы она вызывалась только после успешный scanf
.
Возможно, что-то вроде:
Component tmp; // Scan into a local tmp variable
while (1)
{
r = fscanf(file, "%24s %24s %24s %d %lf",
tmp.type, tmp.model, tmp.unit, &tmp.weight, &tmp.price;
if (r == EOF) break;
if (r == 5)
{
// A complete struct was read so put it into the list
c = newComponent(cl);
*c = tmp; // Copy the tmp struct into the new element in the list
}
else
{
// Didn't get the expected number of vars scanned.
// Add error handling ....
}
}
РЕДАКТИРОВАТЬ
Поскольку OP касается линии Component tmp;
, это альтернативный подход:
char type[25];
char model[25];
char unit[25];
int weight;
double price;
while (1)
{
r = fscanf(file, "%24s %24s %24s %d %lf",
type, model, unit, &weight, &price;
if (r == EOF) break;
if (r == 5)
{
// A complete struct was read so put it into the list
c = newComponent(cl);
strcpy(c->type, type);
strcpy(c->model, model);
strcpy(c->unit, unit);
c->weight = weight;
c->price = price;
}
else
{
// Didn't get the expected number of vars scanned.
// Add error handling ....
}
}