(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:
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