0

I am trying to write an inventory system program and I can only get it display the date or the item name ( should be coke). Depending on if i have the date string or not with fscanf. If I remove that fscanf for the date it shows the item name. if I have the date scanned in it wont show the Item name. Any help?

{
FILE *ifp; 
ifp = fopen(filename, "r");
int x = 0;
fscanf(ifp, "%d",&x);
//printf("%d",x);
for (int i = 0; i < x ; ++i)
{
  
   fgets(inventory_list[i].name,strlen(inventory_list[i].name), ifp);
   fscanf(ifp, "%d", &inventory_list[i].quant);
   fscanf(ifp, "%lf", &inventory_list[i].price);
   fscanf(ifp, "%d", &inventory_list[i].id);
   fscanf(ifp, "%s", inventory_list[i].date);
   

}

and here is the print function I have tried it all as one and i have tried it all separate.

printf("%s",inventory_list[1].name);
printf(" %d \n %.2lf \n %d \n %s ", inventory_list[1].quant,inventory_list[1].price,inventory_list[1].id,inventory_list[1].date);

Here is the structure :

struct inventory_item
{
    
    char name[50];
    int quant;
    double price;
    int id;
    char date[10]; 

};
typedef struct inventory_item inventory;

format of the input file is:

3 total number or items to be sorted
coke name
79 amount of items
2.21 cost of items
12657435 item ID
12/21/2019 DATE 

1 Answers1

1

Here is your code fixed:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

struct inventory_item
{
    char name[50];
    int quant;
    double price;
    int id;
    char date[10];
};

struct inventory_item inventory_list[10];

int main(int argc, char* argv[])
{
    FILE* ifp;
    char* filename = "inventory.txt";
    ifp = fopen(filename, "r");
    if (ifp == NULL) {
        perror(filename);
        return 1;
    }
    int x = 0;
    char buf[128];
    fgets(buf, sizeof(buf) / sizeof(buf[0]), ifp);
    if (sscanf(buf, "%d", &x) != 1) {
        fprintf(stderr, "Read of x failed\n");
        return 1;
    }
    //printf("%d",x);
    if (x > (sizeof(inventory_list) / sizeof(inventory_list[0]))) {
        fprintf(stderr, "Can't read so much items\n");
        return 1;
    }
    for (int i = 0; i < x; i++) {
        printf("Reading item %d\n", i);
        struct inventory_item* item = inventory_list + i;
        if ((fgets(buf, sizeof(buf) / sizeof(buf[0]), ifp) == NULL) ||
            (sscanf(buf, "%50s", item->name) != 1)) {
            fprintf(stderr, "Read of name failed\n");
            return 1;
        }
        if ((fgets(buf, sizeof(buf) / sizeof(buf[0]), ifp) == NULL) ||
            (sscanf(buf, "%d", &item->quant) != 1)) {
            fprintf(stderr, "Read of quant failed\n");
            return 1;
        }
        if ((fgets(buf, sizeof(buf) / sizeof(buf[0]), ifp) == NULL) ||
            (sscanf(buf, "%lf", &item->price) != 1)) {
            fprintf(stderr, "Read of price failed\n");
            return 1;
        }
        if ((fgets(buf, sizeof(buf) / sizeof(buf[0]), ifp) == NULL) ||
            (sscanf(buf, "%d", &item->id) != 1)) {
            fprintf(stderr, "Read of id failed\n");
            return 1;
        }
        if ((fgets(buf, sizeof(buf) / sizeof(buf[0]), ifp) == NULL) ||
            (sscanf(buf, "%10s", item->date) != 1)) {
            fprintf(stderr, "Read of date failed\n");
            return 1;
        }
    }
    fclose(ifp);
    return 0;
}

As you can see, I use fgets to read all lines from the file and sscanf to parse each line. Also added some basic check to avoid buffer/array overflow.

Of course there is yet room for enhancements. For example closing the file before returning in case of error.

fpiette
  • 11,280
  • 1
  • 22
  • 40
  • @GastonLeeTraub If my answer fits your need, please mark it as accepted using the tick mark button on the left of my answer. Other users searching this website will know that a valid answer has been given. – fpiette Jul 02 '21 at 08:06