fgets() is good, when passed valid arguments.
fgets(n,25,stdin) is bad in this code as the value of pointer n is indeterminate.
Instead of using pointer char *n;, use an ample sized array like char buffer[100];. I recommend 2x the expected max size.
Use sizeof to determine array size, not a magic number.
Check fgets() return value.
Avoid using both fgets() and scanf() in the same program. I recommend using fgets() only until your understand why scanf() is problematic.
void fill_boxes(box *boxes, int length) {
// char *n;
char buffer[100];
for (int i = 0; i < length; i++) {
printf("Enter box %d id: ", i+1);
// fgets(n,25,stdin);
if (fgets(buffer, sizeof buffer ,stdin) == NULL) {
printf("No valid input\n");
break;
}
boxes[i].id = strtol(n,NULL,10);
printf("Enter box %d name: ", i+1);
// fgets(boxes[i].name,50,stdin);
if (fgets(buffer, sizeof buffer ,stdin) == NULL) {
printf("No valid input\n");
break;
}
snprintf(boxes[i].name, sizeof boxes[i].name, "%[^\n]", buffer);
// or
buffer[strcspn(buffer, "\n")] = 0; // Lop off potential \n
snprintf(boxes[i].name, sizeof boxes[i].name, "%s", buffer);
}
}
Additional code concerns:
What should happen if the line of input is excessively long?
What should happen with errant input like "123 zxfc\n" for boxes[i].id?
fgets(boxes[i].name,50,stdin); is a problem as rarely is the trailing '\n' desired in boxes[i].name. Zeroing the '\n' after the read, limits reduces by 1, what could be stored in boxes[i].name.