Home > Blockchain >  File handling: Only last item is modified from file in c and file not removed when already given com
File handling: Only last item is modified from file in c and file not removed when already given com

Time:12-17

(If this problem has been asked previously, please do tell. I can't figure out what the exact problem is, therefore, I decided to post this question)

(I have also tried an alternate method where the content of file(inventory) is temporarily stored in memory, then modified before putting it back to the file, but I would like to know why the method below does not work as intended)

I am currently trying to make a cashier program in c. I encountered two problems when trying to decrease the stock items after purchase.

Problem#1 = only last item selected during transaction is successfully decreased from inventory

Problem#2 = the part where it is supposed to remove and rename file doesn't work

This is the part of the code that I think both of the problems reside on:

//modifying item stock after bought
    for (int j = 0; j < item_counter; j  ) {
        char buffer_char[10001];
        int buffer_int[2];
        int  line = 0;
        //printf("--=test num %d %d\n", j, customer.pitem[j].item_id);

        //for getting item price and stock from file
        FILE *flist, *fstock, *tlist, *tstock;
        flist = fopen("item_list.txt", "r");
        fstock = fopen("item_stock.txt", "r");

        //creating or resetting the temporary file
        tlist = fopen("temp_list.txt", "w");
        tstock = fopen("temp_stock.txt", "w");

        while(fgets(buffer_char, 10000, flist) != NULL) {
            if(customer.pitem[j].item_id != (line   1)){
                //getting item name price and stock from file current line
                buffer_char[strlen(buffer_char) - 1] = '\0';
                fscanf(fstock, "%d %d", &buffer_int[0], &buffer_int[1]);

                //printf("fail\n");
                fprintf(tlist, "%s\n", buffer_char);
                fprintf(tstock, "%d %d\n", buffer_int[0], buffer_int[1]);
            }

            else if(customer.pitem[j].item_id == (line   1)) {
                //getting item name price and stock from file current line
                buffer_char[strlen(buffer_char) - 1] = '\0';
                fscanf(fstock, "%d %d", &buffer_int[0], &buffer_int[1]);

                //printf("success\n");
                buffer_int[1] = buffer_int[1] - customer.pitem[j].item_quantity;
                fprintf(tlist, "%s\n", buffer_char);
                fprintf(tstock, "%d %d\n", buffer_int[0], buffer_int[1]);
            }

            line  ;
        }

        //closing all files
        fclose(flist);
        fclose(fstock);
        fclose(tlist);
        fclose(tstock);
        
        //removing the original file
        remove("item_list.txt");
        remove("item_stock.txt");

        //renaming the temporary file
        rename("temp_list.txt", "item_list.txt");
        rename("temp_stock.txt", "item_stock.txt");
    }

This is the content of item_list.txt before any purchase are made:

Susu Kental Manis
Chitatos
Taros
Koka Kola
Bang bang

This is the content of item_stock.txt before any purchase are made (the numbers on the left are prices, while the ones on the right are quantities in inventory):

13000 20
12000 20
7000 20
5000 20
4000 20

This is the entire code for context:

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

//for displaying all items without yes or no
void display_inventory_woyn() {
    FILE *fh_input_list, *fh_input_stock;
    fh_input_list = fopen("item_list.txt", "r ");
    fh_input_stock = fopen("item_stock.txt", "r ");

    char buffer_char[10001];
    int buffer_int[2];
    int line = 0;

    //getting item names from file
    while (fgets(buffer_char, 10000, fh_input_list) != NULL) {
        //fgets(buffer_char, 10000, fh_input_list);
        buffer_char[strlen(buffer_char) - 1] = '\0';
        printf("%d. %s   ", (line   1), buffer_char);

        //getting item price and stock from file
        fscanf(fh_input_stock, "%d %d", &buffer_int[0], &buffer_int[1]);
        printf("Rp.%d   Qty.%d\n", buffer_int[0], buffer_int[1]);

        //incrementing line customer_counter
        line  ;
    }
        

    fclose(fh_input_list);
    fclose(fh_input_stock);
}

int get_date() {
    time_t now = time(NULL);
    struct tm *cur_time = localtime(&now);
    return("%d", cur_time->tm_mday);
}
int get_month() {
    time_t now = time(NULL);
    struct tm *cur_time = localtime(&now);
    return("%d", cur_time->tm_mon   1);
}
int get_year() {
    time_t now = time(NULL);
    struct tm *cur_time = localtime(&now);
    return("%d", cur_time->tm_year   1900);
}
int get_hour() {
    time_t now = time(NULL);
    struct tm *cur_time = localtime(&now);
    return("%d", cur_time->tm_hour);
}
int get_minute() {
    time_t now = time(NULL);
    struct tm *cur_time = localtime(&now);
    return("%d", cur_time->tm_min);
}

typedef struct {
    char month_name[13][20];
}months;

months month_list = {
        "January", 
        "February", 
        "March", 
        "April", 
        "May", 
        "June", 
        "July", 
        "August", 
        "September", 
        "October", 
        "November", 
        "December"
};

typedef struct {
    int date;
    int month;
    int year;

    int hour;
    int minute;
}full_date;

typedef struct {
    char item_name[10001];
    int item_id;
    int item_price;
    int item_quantity;
}item_properties;

typedef struct {
    full_date fdate;
    char customer_name[51];
    item_properties pitem[101];
    
    int total_price;
    int total_quantity;
    int payment;
} order;

order customer;

void cashier_menu() {
    printf ("-------------\n");
    printf (" > CASHIER < \n");
    printf ("-------------\n");
    //getting current date and time
    customer.fdate.date = get_date();
    customer.fdate.month = get_month();
    customer.fdate.year = get_year();
    customer.fdate.hour = get_hour();
    customer.fdate.minute = get_minute();
    //displaying current date and time
    printf("Date: %d %s %d || %d:%d\n", customer.fdate.date, month_list.month_name[customer.fdate.month - 1], customer.fdate.year, customer.fdate.hour, customer.fdate.minute);
    printf ("-------------\n");

    //for getting customer name
    printf("Enter customer name: ");
    fgets(customer.customer_name, 50, stdin);
    //removing \n cased by fgets
    customer.customer_name[strlen(customer.customer_name) - 1] = '\0';
    printf ("-------------\n");

    //display item list
    display_inventory_woyn();
    printf ("-------------\n");

    int item_counter = 0;
    while(true){
        //for getting item price and stock from file
        FILE *flist, *fstock;
        flist = fopen("item_list.txt", "r");
        fstock = fopen("item_stock.txt", "r");

        //asking for item id to buy
        int temp_id = 0;
        printf("Enter item id to buy (enter 0 to finish purchase): ");
        scanf("%d", &temp_id);

        //to consume the \n at the end of scanf
        while ((getchar()) != '\n');

        bool item_existance = false;
        char buffer_char[10001];
        int buffer_int[2];

        //for checknig exit
        if(temp_id <= 0){
            break;
        }

        //checking for item existance
        else {
            int line = 0;
            while (fgets(buffer_char, 10000, flist) != NULL) {
                //getting item name price and stock from file current line
                buffer_char[strlen(buffer_char) - 1] = '\0';

                //when item is found
                if (temp_id == (line   1)) {
                    //fetching item id to struct
                    customer.pitem[item_counter].item_id = temp_id;
                    //get item price and stock from file
                    fscanf(fstock, "%d %d", &buffer_int[0], &buffer_int[1]);
                    //fetching item name to struct
                    strcpy(customer.pitem[item_counter].item_name, buffer_char);
                    //fetching item price to struct
                    customer.pitem[item_counter].item_price = buffer_int[0];
                    //confirming item existance
                    item_existance = true;

                    break;
                }
                //incrementing line
                line  ;
            }

        }

        if(item_existance == true) {
            while(true){
                //asking for how many items to buy
                printf("Enter item quantity: ");
                scanf("%d", &customer.pitem[item_counter].item_quantity);

                //if item quantity is 0
                if(customer.pitem[item_counter].item_quantity == 0 || customer.pitem[item_counter].item_quantity < 0){
                    printf("Please enter an amount greater than 0!\n");
                }

                //if requeested quantity is less than or equal to stock
                else if(customer.pitem[item_counter].item_quantity <= buffer_int[1]){
                    printf("%d Item '%s' added to cart!\n", customer.pitem[item_counter].item_quantity, buffer_char);
                    //adding quantity to total quantity
                    customer.total_quantity  = customer.pitem[item_counter].item_quantity;
                    //adding price to total price
                    customer.total_price  = (customer.pitem[item_counter].item_quantity * buffer_int[0]);
                    break;
                }

                //if requested quantity is grater than stock
                else{
                    printf("Quantity requested: %d, is more than availability: %d\n", customer.pitem[item_counter].item_quantity, buffer_int[1]);
                }
            }

            //incrementing item counter
            item_counter  ;
            printf("\n");
        }

        else {
        printf("Item index %d not found!\n", temp_id);
        }
        
        fclose(flist);
        fclose(fstock);
        
    }

    //displaying total price
    printf ("\n-------------\n");
    printf("Your total price for %d item is: Rp.%d\n", customer.total_quantity, customer.total_price);

    //asking for payment
    while(true){
        printf("Enter payment: Rp.");
        scanf("%d", &customer.payment);
        //to consume the \n at the end of scanf
        while ((getchar()) != '\n');

        if (customer.payment >= customer.total_price){
            printf("Change: Rp.%d\n", customer.payment - customer.total_price);
            printf ("-------------\n");
            break;
        }
        else{
            printf("Payment is less than total price!\n");
        }
    }

    //printf("     item types %d\n", item_counter);


//!function for modifiying files---------------------------------------------------------------------------------------------------

    //modifying item stock after bought
    for (int j = 0; j < item_counter; j  ) {
        char buffer_char[10001];
        int buffer_int[2];
        int  line = 0;
        //printf("--=test num %d %d\n", j, customer.pitem[j].item_id);

        //for getting item price and stock from file
        FILE *flist, *fstock, *tlist, *tstock;
        flist = fopen("item_list.txt", "r");
        fstock = fopen("item_stock.txt", "r");

        //creating or resetting the temporary file
        tlist = fopen("temp_list.txt", "w");
        tstock = fopen("temp_stock.txt", "w");

        while(fgets(buffer_char, 10000, flist) != NULL) {
            if(customer.pitem[j].item_id != (line   1)){
                //getting item name price and stock from file current line
                buffer_char[strlen(buffer_char) - 1] = '\0';
                fscanf(fstock, "%d %d", &buffer_int[0], &buffer_int[1]);

                //printf("fail\n");
                fprintf(tlist, "%s\n", buffer_char);
                fprintf(tstock, "%d %d\n", buffer_int[0], buffer_int[1]);
            }

            else if(customer.pitem[j].item_id == (line   1)) {
                //getting item name price and stock from file current line
                buffer_char[strlen(buffer_char) - 1] = '\0';
                fscanf(fstock, "%d %d", &buffer_int[0], &buffer_int[1]);

                //printf("success\n");
                buffer_int[1] = buffer_int[1] - customer.pitem[j].item_quantity;
                fprintf(tlist, "%s\n", buffer_char);
                fprintf(tstock, "%d %d\n", buffer_int[0], buffer_int[1]);
            }

            line  ;
        }

        //closing all files
        fclose(flist);
        fclose(fstock);
        fclose(tlist);
        fclose(tstock);
        
        //removing the original file
        remove("item_list.txt");
        remove("item_stock.txt");
        //renaming the temporary file
        rename("temp_list.txt", "item_list.txt");
        rename("temp_stock.txt", "item_stock.txt");
    }

//--------------------------------------------------------------------------------------------------------------------

    //printing history to console
    char invoice_ask;
    printf("\n");
    printf("Do you want to print the invoice? (y/n): ");
    scanf("%c", &invoice_ask);
    //checking for invoice print
    if (invoice_ask == 'y'){
        //clear console
        system("cls");

        printf("------------------------\n");
        printf(" >> CUSTOMER INVOICE << \n");
        printf("------------------------\n");

        printf("Customer name: %s\n", customer.customer_name);
        printf("Transaction Date: %d %s %d || %d:%d\n", customer.fdate.date, month_list.month_name[customer.fdate.month - 1], customer.fdate.year, customer.fdate.hour, customer.fdate.minute);
        printf("Items Bought:\n");
        printf ("-------------\n");
        //printing purchsed items
        for(int i = 0; i < item_counter; i  ){
            printf("%d. %s || Rp.%d || %d\n", (i   1), customer.pitem[i].item_name, customer.pitem[i].item_price, customer.pitem[i].item_quantity);
        }
        printf ("-------------\n");

        printf("Total quantity: %d\n", customer.total_quantity);
        printf("Total price: Rp.%d\n", customer.total_price);
        printf("Payment: Rp.%d\n", customer.payment);
        printf("Change: Rp.%d\n", customer.payment - customer.total_price);
        printf ("-------------\n");
        printf("Thank you for shopping with us!\n");
    }
    else {
        printf("Thank you for shopping with us!\n");
    }
    //back to main menu
    printf("going back to menu...");
    //main_menu();
}


//dirver code
int main() {
    cashier_menu();
    return 0;
}

Here are some input output examples and how the changes are reflected in temp_stock.txt:

enter image description here

enter image description here

enter image description here

enter image description here

As seen from 2 set of examples above, only the last added/purchased item is the only one that was successfully modified from the inventory when being copied to temp_stock.txt.

Thank you in advance.

CodePudding user response:

Try resetting the file pointer with the fseek() function, this would tell the program to begin reading from the beginning of a new file, without it it would either just start reading from wherever, or it would pick up at the position of the last file

CodePudding user response:

First, it looks like the loop that modifies the item stock only takes the last item selected into account. This is because you are overwriting the contents of the "temp_list.txt" and "temp_stock.txt" files in each iteration of the loop. As a result, only the last item selected will be present in the files at the end of the loop.

To fix this issue, you can move the code that opens the "temp_list.txt" and "temp_stock.txt" files and the code that removes the original "item_list.txt" and "item_stock.txt" files outside of the loop. This way, the contents of the "temp_list.txt" and "temp_stock.txt" files will be appended to in each iteration of the loop, rather than overwritten.

Second, the code renames the "temp_list.txt" and "temp_stock.txt" files to "item_list.txt" and "item_stock.txt" before the loop is finished. This means that if there is an error in the loop (e.g. if one of the files cannot be opened), the original "item_list.txt" and "item_stock.txt" files will be removed, but the updated versions will not be renamed, resulting in a loss of data.

To fix this issue, you can move the code that renames the "temp_list.txt" and "temp_stock.txt" files to "item_list.txt" and "item_stock.txt" outside of the loop, after the loop is finished. This way, the original "item_list.txt" and "item_stock.txt" files will only be removed and replaced by the updated versions if the loop is successful

  • Related