The purpose of this parsing loop is to update the list of products from the contents of the file. The while loop has problems:
- the
fscanf() format uses %s which is risky as unexpectedly long input may cause a buffer overflow, attempting to write beyond the end of the serial destination array.
- comparing the
fscanf() return value to EOF is not reliable: you should instead check the number of successful conversions, which should be 2.
- the
\n at the end of the format string matches any white space, it is not a reliable way to test for the end of line.
- the
for loop attempts to locate the product in the listProducts array and add an entry if it was not found. The loop logic is incorrect for this purpose: you always increment i.
It is recommended to read the file one full line at a time with fgets(), parse the line with sscanf() and report any parsing issues.
Here is a modified version:
int load_products(struct product *listProducts, int count, FILE *f) {
char buf[128];
int i = 0;
while (fgets(buf, sizeof buf, f)) {
char serial[30];
int n;
int j;
if (sscanf(buf, "%29s%d", serial, &n) != 2) {
fprintf(stderr, "invalid format: %s\n", buf);
continue;
}
for (j = 0; j < i; j++) {
if (strcmp(serial, listProducts[j].serialID) == 0)
break;
}
if (j < i) {
/* product was found: update the count */
listProducts[j].n_items += n;
} else {
/* product was not found: add an entry at the end */
if (i >= count) {
fprintf(stderr, "too many products, maximum: %d\n", count);
break;
}
strcpy(listProducts[i].serialID, serial);
listProducts[i].n_items = n;
i++;
}
}
return i;
}