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,983
  • 1
  • 24
  • 46