Method to Batch Update on C Programming - c

I need to do this Batch Update on a products list. This batch update has to retrieve EVERY product from within the database and get it's "quantity in Order". This "Quantity in Order" then has to be added to the current stock:
For e.g:
Current in Stock : 100
In order: 150
After the Batch Update they have to be:
Current in Stock :250
In Order: 0
I have done this method (see below) BUT when I run it, it's not updating my Stock and neither my Order.
void batchUpdate()
{
printf ("\n\n\n\n\t\t ********** Batch Update *******\n \n \n");
int tempOrder;
int tempStock;
int tempAdding;
if ((pfp = fopen("products.dat","r+b")) == NULL)
{
printf ("Error! Cannot Open Products.dat!\n");
printf ("Returning to Main Menu\n");
system ("PAUSE");
orderMainMenu();
}
while (fread(&p,STRUCTSIZE,1,pfp) == 1)
{
tempOrder = p.pOrder;
tempStock = p.pStock;
tempAdding = tempOrder + tempStock;
p.pOrder = 0;
p.pStock = tempAdding;
fwrite (&p,STRUCTSIZE,1,pfp);
}
fclose (pfp);
printf ("Orders and Stock Updated!\n");
printf ("Returning to Main Menu!\n");
system ("PAUSE");
orderMainMenu();
}
I tried using fseek (pfp, -STRUCTSIZE,SEEK_CUR); but that turned my program into an infinite Loop.
Also when I tried to use show All products in database, they skipped my first record and just went into an infinite loop showing the last record only. I just have to end up deleting the products.dat file from the system and redo it again.
Any suggestion? I do believe that there is something wrong with the fseek().
Thanks in advance

Found the error,
did not do an fflush (pfp); after the fwrite();
This is the final working code;
void batchUpdate()
{
printf ("\n\n\n\n\t\t ********** Batch Update *******\n \n \n");
int tempOrder;
int tempStock;
int tempAdding;
if ((pfp = fopen("products.dat","r+b")) == NULL)
{
printf ("Error! Cannot Open Products.dat!\n");
printf ("Returning to Main Menu\n");
system ("PAUSE");
orderMainMenu();
}
while (fread(&p,STRUCTSIZE,1,pfp) == 1)
{
tempOrder = p.pOrder;
tempStock = p.pStock;
tempAdding = tempOrder + tempStock;
p.pOrder = 0;
p.pStock = tempAdding;
fseek (pfp,-STRUCTSIZE,SEEK_CUR);
fwrite (&p,STRUCTSIZE,1,pfp);
fflush(pfp); //THIS WAS EMITTED AND WAS CAUSING PROBLEMS
}
fclose (pfp);
printf ("Orders and Stock Updated!\n");
printf ("Returning to Main Menu!\n");
system ("PAUSE");
orderMainMenu();
}

Related

C file-handling program exited without running whole program

I'm using Dev-C++ (we're required to use either Turbo-C++ or Dev-C++). I'm supposed to delete one student (DATA 2) from a student record. Here is the data that we were given:
DATA 1:
2021-10-693
Clarisse
BSCS 1
1.00, 1.00, 1.00, 1.25, 1.25
DATA 2:
2021-10-705
Kricel
BSCS 1
1.00, 1.25, 1.00, 1.00, 1.25
DATA 3:
2021-01-256
Rafael
BSCS 1
1.00, 1.00, 1.00, 1.00, 1.25
We were given a student.dat file created using Turbo-C++ but I can't open it in Dev-C++ so I created my own student.dat by copy-pasting my teacher's code from Turbo-C++ to Dev-C++. The only thing I changed in this code is removing clrscr(); and replacing it with system("cls");:
/* This program will allow saving of records in the disk */
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
typedef struct{
char No[12];
char Name[25];
char Crsyr[10];
float Grade[5];
}Student_Record;
int main()
{
FILE *STUDFILE; /* defining FILE variable */
Student_Record STUDENT[50],TEMPREC;
int i,j,ns;
float TGrade;
char Temp,FName[15];
do{
system("cls");
printf("How many student records (max. of 50) ? ");
scanf("%d",&ns);
if ((ns<1)||(ns>50))
{
printf("\nInvalid Input!!!");
printf("\n\nPress Any Key To Continue...");
getch();
}
}while((ns<1)||(ns>50));
scanf("%c",&Temp);
for(i=0;i<ns;i++)
{
system("cls");
printf("<## STUDENT's INFORMATION ##>\n\n");
printf("Student No. : ");
gets(STUDENT[i].No);
printf("Student Name : ");
gets(STUDENT[i].Name);
printf("Course and Year: ");
gets(STUDENT[i].Crsyr);
printf("List of grades:\n");
for(j=0;j<5;j++)
{
printf("\tGrade No. %d => ",j+1);
scanf("%f",&TGrade);
STUDENT[i].Grade[j]=TGrade;
}
printf("\nPress any key to continue...");
getch();
scanf("%c",&Temp);
}
printf("\n\nEnter Filename where records will be saved => ");
gets(FName);
printf("\n\nSaving of Records being process...");
STUDFILE=fopen(FName,"w"); /* fopen-file opening; "w" - generate new file or overwrite existing file */
for(i=0;i<ns;i++)
{
TEMPREC=STUDENT[i];
fwrite(&TEMPREC,sizeof(TEMPREC),1,STUDFILE); /* fwrite - save records in the disk */
}
fclose(STUDFILE); /* fclose - file closing */
printf("Saving of Records Completed!!!\n\n");
printf("Press Any Key To Exit...");
getch();
return (0);
}
Here is the student.dat file:
2021-10-693 Clarisse þÿÿÿÿÿÿÿþÿÿÿÿBSCS 1 €? €? €? ? ?2021-10-705 Kricel Po `Of°û BSCS 1 €? ? €? €? ?2021-10-256 Rafael °û ˜im°û ˜im°ûBSCS 1 €? €? €? €? ?
My plan is to:
Open student.dat for reading
Open temp.dat for writing
Read content of student.dat
Compare studNo to data in student.dat
If studNo is not equal to student no. of Kricel, write it in temp.dat
If studNo is equal to student no. of Kricel, don't write in temp.dat
Close both files
Open temp.dat for reading
Open student.dat for writing
Overwrite student.dat with content from temp.dat
Close both files
Open student.dat for reading
Display student.dat
And here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
typedef struct
{
char no[12];
char name[25];
char crsYr[10];
float grade[5];
} studentRecord;
int main()
{
FILE *studFile, *tempFile;
studentRecord student[50], tempStudRec, tempFileRec;
int i = 0, j = 0, k = 0, found = 0;
float tGrade = 0.00;
char temp, fName[15], studNo[12], resp1, resp2;
system("cls");
printf("Enter file name of the record you want to alter: ");
gets(fName);
printf("Enter student no. of student you want to delete: ");
gets(studNo);
printf("Are you sure you want to remove this student (Y/N)? ");
scanf("%c", &resp1);
if (toupper(resp1) == 'Y')
{
printf("\nRetrieving records from %s...", fName);
//Sleep(2000);
printf("\nDeleting student %s from %s...", studNo, fName);
//Sleep(2000);
// Opens both files
studFile = fopen(fName, "r");
if (studFile == NULL)
{
printf("File opening is unsuccessful.");
return 1;
}
tempFile = fopen("temp.dat", "w");
// Reads student.dat
k = 0;
fread(&tempStudRec, sizeof(studentRecord), 1, studFile);
while(!feof(studFile))
{
student[k] = tempStudRec;
fread(&tempStudRec, sizeof(studentRecord), 1, studFile);
k++;
}
// Compare studNo to data in student.dat
for (i = 0; i < k; i++)
{
// If content is not equal to student no. of Kricel
if (strcmp(studNo, student->no) != 0)
{
// Write in temp.dat
tempFileRec = student[i];
fwrite(&tempFileRec, sizeof(studentRecord), 1, tempFile);
}
}
// Closes both files
fclose(studFile);
fclose(tempFile);
// Opens both files again
tempFile = fopen("temp.dat", "r");
if (tempFile == NULL)
{
printf("File opening is unsuccessful.");
return 1;
}
studFile = fopen(fName, "w");
// Reads temp.dat
k = 0;
fread(&tempFileRec, sizeof(studentRecord), 1, tempFile);
while(!feof(studFile))
{
student[k] = tempFileRec;
fread(&tempFileRec, sizeof(studentRecord), 1, tempFile);
k++;
}
// Copies temp.dat content to student.dat
for (i = 0; i < k; i++)
{
// Write in student.dat
tempStudRec = student[i];
fwrite(&tempStudRec, sizeof(studentRecord), 1, studFile);
}
// Closes both files
fclose(studFile);
fclose(tempFile);
// Opens student.dat for reading
studFile = fopen(fName, "r");
// Displaying records
printf("Student deleted!");
printf("\nDo you want to view record (Y/N)? ");
scanf("%c", &resp2);
if (toupper(resp2) == 'Y')
{
for(i = 0; i < k; i++)
{
system("cls");
printf("<## STUDENT INFORMATION ##>\n\n");
printf("Student No. : %s\n", student[i].no);
printf("Student Name : %s\n", student[i].name);
printf("Course and Year: %s\n", student[i].crsYr);
printf("List of Grades:\n");
for(j = 0; j < 5; j++)
{
printf("\tGrade No. %d => %0.2f\n", j + 1, student[i].grade[j]);
}
printf("\nPress any key to continue...");
}
}
// Closes student.dat
fclose(studFile);
}
return 0;
}
This is what the output looks like:
Enter file name of the record you want to alter: student.dat
Enter student no. of student you want to delete: 2021-10-705
Are you sure you want to remove this student (Y/N)? Y
Retrieving records from student.dat...
Deleting student 2021-10-705 from student.dat...
--------------------------------
Process exited after 16.78 seconds with return value 3221225477
Press any key to continue . . .
I checked student.dat after running the code and it's empty. Meanwhile, temp.dat contains all the contents of student.dat I showed above, including the student I'm supposed to delete. Can anyone give me an idea why is student.dat empty after running this program? And why wasn't student 2021-10-705 deleted? I'm having a hard time understanding online tutorials since we kinda just skimmed over pointers and we haven't discussed malloc(), etc. yet.
Rather than analyzing your two programs for you, I'll try to suggest how you can figure out what's going on.
Check library function call return values
Library function calls don't always succeed! When you try to open a new file - the directory might not be writeable; when you write data to disk - the disk may be full; etc. I'm not saying this is what happens in your case, but you should rarely, or perhaps never, assume a library function succeeds, if its return value can indicate an error.
Always check that return value; and if it doesn't indicate success, print a message describing the failure. See, for example, answers to this question:
Error handling in C code
on how that looks.
Use a debugger
It is often not sufficient to just scrutinize the code, or deduce from the output what actually happens when the program runs. You can, and probably should, actively debug a misbehaving program by tracking its execution with a debugger program.
Here are two Stackoverflow questions about debugging on Linux and on Windows:
How to debug a C program
How do you debug a C program on Windows?
(other platforms also have debugging tools available.)
Consider flushing the standard output stream
When your program does not seem to run to conclusion, you could insert fflush() calls at relevant 'suspicious' points in your code to ensure that whatever you printed up to that point does actually become visible on the output, rather than waiting in the output stream's buffers.
Note that, other than for debugging purposes, we generally want to avoid flushing.

How to pass a text file into an array in c?

Noob programmer here...so please bear with me. I'm trying to pass an existing text file into an array however once my main Menu loads the information that once existed in that file goes away, even if I don't make any changes. it is just not keeping the information. The Program is supposed to allow the user to either create a new file or update and/or load an existing file. Any ideas on how to fix this issue? Thank you all!
char fileName[20] = "";
void loadEmployee()
{
FILE* fPtr;
char singleLine[150];
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf_s("%s", fileName, 20);
}
fopen_s(&fPtr, fileName, "r");
while (!feof(fPtr))
{
fgets(singleLine, 150, fPtr);
puts(singleLine);
}
fclose(fPtr);
}
void saveEmployee()
{
FILE* fPtr;
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf_s("%s", fileName, 20);
}
fopen_s(&fPtr, fileName, "w");
for (int i = 0; i < numEmps; i++)
{
fprintf(fPtr, "%s %f %f\n", emps[i].emps.name,
emps[i].emps.rate, emps[i].emps.hours);
}
fclose(fPtr);
}
void loadMenu()
{
int i = 0;
printf("1. Load from a file \n");
printf("2. Keyboard \n");
scanf_s("%d", &choice);
switch (choice)
{
case 1: loadEmployee();
break;
default:
break;
}
do
{
printf("\nMAIN MENU\n");
printf("1.Add Employee\n");
printf("2.Edit Employee\n");
printf("3.Print Employee\n");
printf("4.Print ALL employees\n");
printf("5.Exit\n");
scanf_s("%d", &choice);
switch (choice)
{
case 1: NameInput();
break;
case 2: printf("Choose employee: \n");
for (int i = 0; i < numEmps; i++)
{
printf("%d. %s \n", i + 1,
emps[i].emps.name);
}
scanf_s("%d", &choice);
empUpdate(choice - 1);
break;
case 3: printf("Choose employee: \n\n");
for (int i = 0; i < numEmps; i++)
{
printf("%d) %s \n", i + 1,
emps[i].emps.name);
}
scanf_s("%d", &choice);
printf("%s \n", emps[choice -
1].emps.name);
printf("%.2f \n", emps[choice -
1].emps.hours);
printf("%.2f \n", emps[choice -
1].emps.rate);
break;
case 4: PayOutput();
break;
case 5: printf("Quitting program!");
saveEmployee();
return;
default: printf("Invalid choice try again \n\n");
break;
}
} while (choice != 5);
}
int main()
{
struct information empsi[20];
loadMenu();
}
Your function loadEmployee only writes to a char[] that is local to the function (which means it’s discarded at the end).
When the program exits, you « save » the employee by reopening your file in write mode, which clears it, and what follows probably doesn’t do much, so the file remains empty.
Try actually returning or storing the data from the file outside your function so it can be reused later.
As #hugo said, the program reads the file but doesn't store the contents. This means emps will be empty. When you quit you open the file for writing deleting its contents. Beause emps is empty, nothing is written.
This can be solved by reading similar to how you're writing. I don't know exactly what emps looks like, but something like this.
for( numEmps = 1; fgets(singleLine, 150, fPtr); numEmps++ ) {
// I'm assuming emps is preallocated.
struct Employee emp = emps[numEmps-1];
sscanf(singleLine, "%80s %f %f",
emp.emps.name,
&emp.emps.rate,
&emp.emps.hours
);
}
Notice rather than using feof I'm looking at the return value of fgets. As Edward Karak mentioned, when reading lines don't check for eof.
Other issues in the code...
You're not checking whether your files actually opened.
fopen_s(&fPtr, fileName, "r");
if( !fPtr ) {
perror(fileName);
exit(1);
}
The code uses a lot of global variables. This leads to hard to understand code as anything can change those globals at any time. Instead, take advantage of function arguments and return values. Then you can completely understand a function just by looking at it.
For example, loadEmployee should take the struct to populate and the filename to read from, then return how many it read. saveEmployee is similar.
int loadEmployee(struct Employee *emps, char *fileName) {
...
return numEmps;
}
void saveEmployee(struct Employee *emps, char *fileName) {
...
}
Neither should be in charge of asking the user for the filename. This should be handled by the caller. Functions should do one thing; it makes them simpler and more flexible.
We can move the logic to get the filename into a function. Rather than using a global, we use a static variable. This variable is still local to the function, but does not get reset. getFileName remembers the filename.
char *getFileName() {
static char fileName[80] = "";
if (strcmp(fileName, "") == 0)
{
printf("\nWhat's the name of the file? ");
scanf("%20s", fileName);
}
return fileName;
}
...
switch(choice) {
case 1:
numEmps = loadEmployee(emps, getFileName());
break;
...
case 5:
printf("Quitting program!");
saveEmployee(emps, getFileName());
return;
}
...
These are not the source of your problem, but they will help structure your code so it's easier to understand and debug.

How to properly look for a string in a file?

In this function, I am displaying a .txt document to the screen, which works, however, I am trying to read the file document and scan the document for the word EMPTY as I have it saved as a string variable. It should be noted that I am counting the time EMPTY is in the file and later printing the times it was would in the file along with on another thing. My first question is am I doing this correct?
void allSeats(void)
{
int position = 0;
int count = 0;
char gone[6] = "EMPTY";
system("cls");
retry:
fseatArrangement = fopen("airlineSeatingArrangment.txt", "r");
while (fgets(econoAirSeatArrangement, 1000, fseatArrangement) != NULL)
printf(econoAirSeatArrangement);
fclose(fseatArrangement);
while (count < FULL)
{
fgets(econoAirSeatArrangement, 1000, fseatArrangement);
fscanf(fseatArrangement,"%s", &gone);
count++;
}
printf("There are %d seats vacant at the moment\nThere are %d seats with no vacancy at the moment \n",count, FULL-count);
printf("Enter Zero(0) Key to return to menu at anytime.");
scanf("%d", &position);
if (position == 0)
{
system("cls");
menu();
}
else
{
system("cls");
printf("INVALID INPUT! Please try again.\n");
goto retry;
}
system("pause");
return;
}
The main problem is here
fgets(econoAirSeatArrangement, 1000, fseatArrangement);
you have already closed the file pointer using fclose(), and yet, you try to use it. It causes undefined behavior.
That said,
printf(econoAirSeatArrangement); appears wrong. If you do not wish to have any format conversion specification you can stick to puts().
You must check the return value of fopen(), fgets(), fscanf() etc. for success before using the returned value / scanned value.

Database not outputting on C even though I'm saving

I am doing an Order's Database in which in this case deals with a transaction.
The procedure is as follows:
First the Customer enters his ID. If it is not found, it exits to the main menu otherwise it proceeds (The Customer MUST have an ID registered within the database which is stored on another file)
It asks which Product they are going to buy (it asks for PRODUCT NAME [that's how lecturer wanted it by Name] and if it is not found it exists otherwise it proceeds
It asks how many they are going to buy and checks whether there is enough in Stock. If it is it proceeds otherwise asks the user whether they want to input another number or exit
Price is calculated automatically and a Confirmation is ASKED. if Customer CONFIRMS then the saving is done otherwise it exits to Main Menu
Now my problem is that even though my STRUCT is saving, whenever I come to output ANY ORDER in the database (for now testing as I need the LAST order of a customer first) The Database is always showing as EMPTY. Below is the Coding [it is rather long I am sorry but I cannot understand where is wrong] and also will provide the List All function.
Screenshots are provided as well to understand better how the program works:
void customerOrder()
{
int checkID = 0; //variable to hold the ID input
char ch;
char ch1;
char ch2;
char option;
char tempName [100];
int order = 0;
int tempStock = 0;
float tempPrice = 0;
printf ("\n\n\n\n\t\t ************* Add Customer Order *************\n \n \n");
// ----------- LOADING OF THE 3 DATA FILES -----------//
if ((ofp = fopen ("orders.dat","a+b")) == NULL)
{
fputs ("Error! Cannot open orders.dat\n",stderr);
system ("PAUSE");
orderMainMenu();
}
rewind (ofp);
if ((cfp = fopen ("customers.dat","r"))== NULL)
{
fputs ("Error! Cannot open customers.dat\n",stderr);
system ("PAUSE");
orderMainMenu();
}
rewind (cfp);
if ((pfp = fopen ("products.dat","r+b"))== NULL)
{
fputs ("Error! Cannot open products.dat\n",stderr);
system ("PAUSE");
orderMainMenu();
}
rewind (pfp);
//-------- Confirm whether to start Order ------------//
printf ("WARNING: In order for an Order to be made, the Customer must be in the Database\n");
printf ("Are you sure you want to continue? Y or N\n");
while (getchar() !='\n')
{
}
ch1 = getchar ();
if (ch1 == 'Y' || ch1 == 'y')
{
// ---- INPUT OF CUSTOMER ID --------------//
printf ("\nPlease Enter ID: ");
while (scanf ("%d",&checkID) == 0)
{
printf ("\n\nInvalid Input!!!\n");
printf ("Either you have entered a Letter!!\n");
printf ("Press 'Y' to enter another ID or any key to return to MainMenu\n\n");
while (getchar()!='\n')
{
}
option = getchar();
if (option == 'Y' || option == 'y')
{
printf ("\nPlease Enter Another ID Number:\n");
}
else
{
printf ("\nReturning to Order Management Menu\n");
system ("PAUSE");
fflush(stdin);
orderMainMenu();
}
}
//---------- CHECK WHETHER ID EXISTS OTHERWISE EXIT TO MENU --------------//
while (fread (&c, STRUCTSIZEC,1,cfp) == 1)
{
if (c.ID == checkID)
{
clrscr();
printf ("\n\n\n\n\t\t ************* Add Customer Order *************\n \n \n");
// SHOWS WHICH ID IS BEING SERVED //
printf ("\n\nNew Order For ID: %d\n", c.ID);
// ASKS WHICH PRODUCT TO BUY //
printf ("\nWhich Product do you want to buy?\n\n");
printf ("WARNING! Product Name is CASE SENSITIVE:\n");
// INPUT NAME //
printf ("Product Name: ");
while (getchar() !='\n')
{
}
fgets (tempName, 100, stdin);
while (fread (&p, STRUCTSIZEP,1,pfp)== 1)
{
if (strncmp (tempName,p.pName,sizeof(tempName)) == 0)
{
// --- SHOWING ID and WHICH PRODUCT CUSTOMER IS GOING TO BUY -- //
clrscr ();
printf ("\n\n\n\n\t\t ************* Add Customer Order *************\n \n \n");
printf ("Order for ID: %d\n", c.ID);
printf ("Product Name: %s\n\n", p.pName);
tempStock = p.pStock;
printf ("How many do you wish to buy?\n");
printf ("Currently there is %d in Stock", tempStock);
printf ("Order: ");
while (scanf ("%d",&order) == 0)
{
printf ("Invalid Order! Only Numbers are allowed!\n");
while (getchar() !='\n')
{
}
}
//---- CHECK WEHTHER ORDER IS BIGGER THAN WHAT IS FOUND IN STOCK ----//
//---- IF YES ASK IF USER WANTS TO INPUT ANOTHER NUMBER OR EXIT ----//
while (order > tempStock)
{
printf ("There is not enough items in Stock to satisfy that quantity!\n");
printf ("Do you want to enter another quantity? 'Y' for yes, any key to return to Menu\n");
fflush (stdin);
ch2 = getchar();
if (ch2 == 'Y' || ch2 == 'y')
{
printf ("Please enter another quantity:\n");
scanf ("%d",&order);
}
else
{
printf ("Order Canceled! Returning to Main Menu");
system ("PAUSE");
fclose (cfp);
fclose (ofp);
fclose (pfp);
orderMainMenu();
}
}
printf ("\nTotal Price for this Order will be:\n");
tempPrice = (order * p.pPrice);
printf ("Total: %.2f\n", tempPrice);
// ---- SHOW THE TRANSACTION OF THE USER AND ASK WHETHER TO CONFIRM ---- //
clrscr();
printf ("\n\n\n\n\t\t ************* Add Customer Order *************\n \n \n");
printf ("This is the Customer's Overview of Purchase:\n\n");
printf ("Customer's ID: %d\n",c.ID);
printf ("Customer's Product: %s",p.pName);
printf ("Order: %d\n",order);
printf ("Total Price: %.2f\n\n",tempPrice);
printf ("\n\n----------------------------------------\n\n");
printf ("Are you sure you of this transaction?\n");
printf ("Warning: After Confirming you cannot change the Order!\n");
printf ("Press 'Y' to confirm the Transaction otherwise press 'N' to cancel the order and return to Main Menu\n");
while (getchar() !='\n')
{
}
ch = getchar();
if (ch == 'N' || ch == 'n')
{
printf ("Transaction CANCELLED! Returning to Order Main Menu!\n");
system ("PAUSE");
orderMainMenu();
}
else if (ch == 'y' || ch == 'Y')
{
tempStock = (tempStock - order);
p.pStock = tempStock; //Updates the new stock number in Products' Database
fseek (pfp,-STRUCTSIZEP,SEEK_CUR);
fwrite(&p, STRUCTSIZEP,1,pfp);
fclose (pfp);
o.quantity = order;
o.cID = c.ID;
o.price = tempPrice;
strncpy(o.pName,p.pName, sizeof(p.pName));
o.timer = time(NULL);
fwrite (&o,STRUCTSIZEO,1,ofp);
fclose (ofp); //Closing of Files
fclose (cfp);
fclose (pfp);
printf("The Transaction Order saved is as follows:\n");
printf("ID: %d\nProduct: %sQuantity: %d\nPrice: %.2f\n",o.cID,o.pName,o.quantity,o.price);
printf("Transaction Made at: %s\n",asctime(localtime(&o.timer)));
system ("PAUSE");
orderMainMenu();
}
}
}
}
}
}
else
{
printf ("Returning to Order Main Menu\n");
system ("PAUSE");
orderMainMenu();
}
}
ListAll method:
void oListAll()
{
order o;
printf ("\n\n\n\n\t\t ********** Current Products in the Database *******\n \n \n");
//--------------- LOADING OF FILE ------------ //
if ((ofp = fopen ("orders.dat","rb")) == NULL)
{
fputs ("Cannot open products.dat file!\n",stderr);
printf ("Returning to Order Main Menu\n");
system ("PAUSE");
orderMainMenu();
}
rewind (ofp);
// --------- START TO TRAVERSE THE DATABASE AND OUTPUT DATA -------- //
printf ("Current Orders in the Database:\n");
while (fread (&o, STRUCTSIZEO,1,pfp)==1)
{
printf (" Name: %s Price: %.2f\n In Stock: %d\n\n", o.pName, o.price, o.quantity);
}
system ("PAUSE");
productMainMenu();
}
These are the screenshots:
http://tinypic.com/r/110x7c2/6
http://tinypic.com/r/1446ya/6
http://tinypic.com/r/315iy3s/6
http://tinypic.com/r/15xo4lt/6
http://tinypic.com/r/2ze9wfr/6
http://tinypic.com/r/jtx8xw/6
I know it's rather long but please bear with me, I've been over 4 hours trying to figure out what's wrong with it. Thanks a bunch
Your oListAll() function opens FILE *ofp, but reads from pfp. Try reading from ofp
As this is not the whole program I can't find the issue but my guess it that it has something to do with your file pointers being global vars. You should make them local and always ensure they are closed properly.
I would break up the customerOrder() function in to smaller functions. This will make your code much easier to read, debug, and modify. For example (this is just pseudo-code, you have to fill in the blanks):
void customerOrder()
{
int checkId = getCustomerID(); // Checks the DB to see if user exists
bool productExists = checkProduct(tempName); // Checks the DB to see if product exists
int productCount = getProductCount(tempName); // Checks the DB to get count of items in stock
saveOrder(checkId, tempName, order); // Save the order
}
// Save the order in DB. Ensures FILE pointers are closed when done
void saveOrder(int customerID, const char * productName, int count)
{
order o;
// Create the order here....
FILE *ofp = fopen ("orders.dat","ab");
if (NULL != ofp) {
fwrite (&o,STRUCTSIZEO,1,ofp);
fclose (ofp); //Closing of Files
}
}

Reading one file, parsing, and writing another

Consider the file,
L,12/5/2008,Blacktown
C,Willy Wonker,10.00
C,Adolph Hitler,20.00
C,Attila the Hun,30.00
C,Idi Amin,40.00
C,Ghengis Khan,50.00
T,150.00
L,13/5/2008,Parramatta
C,Attila the Hun,100.10
C,Willy Wonker,200.20
C,Ghengis Khan,300.30
T,600.60
L,14/5/2008,Mount Druitt
C,Adolph Hitler,1000.00
T,2000.00
L,15/5/2008,Penrith
T,0.00
L,16/5/2008,Chatswood
C,Ghengis Khan,1.00
C,Idi Amin,10.00
C,Adolph Hitler,100.00
C,Attila the Hun,1000.00
T,1111.00
I need to write a program that opens the file Collections.txt, reads it and formats it in the given order, and writes it to another file called Reports.txt. I need to have the date, a tab, and then the name. Then a new line and the names, a tab, and the amount. Repeat until a T is detected; this signals we have no more collections for the above location. Then rinse and repeat for every location until it reaches the end of the file and a final total must be displayed.
Here is the code I have written,
/*
This program collects data and writes it to a specific file.*/
#include <stdio.h>
#include <stdlib.h>
void debt_calculator();
void main()
{
printf("This is a debt collection program:\n ");
debt_calculator();
scanf("%*c");
}
void debt_calculator()
{
char code;
int date [40];
char location [40];
char name [40];
float amount = 0;
float total = 0;
float grand_total;
int ctr = 0;
FILE * Collections;
Collections=fopen("C:\\Users\\Nick\\Documents\\Visual Studio 2010\\Projects\\Assignment2\\Assignment2\\Collections.txt","r");
if(Collections==NULL)
{
printf("file not open:\n");
exit(1);
}
FILE * Report;
if((Report=fopen("C:\\Users\\Nick\\Documents\\Visual Studio 2010\\Projects\\Assignment2\\Assignment2\\Report.txt","w"))==NULL)
{
printf("can not open file: \n");
exit(1);
}
fscanf(Collections,"%c,",&code);
while(code == 'L')
{
fscanf(Collections,"%[^,],%s%*c",date,location);
fprintf(Report,"Date: %s \t Location: %s \n\n",date, location);
fscanf(Collections,"%c,",&code);
}
for(code == 'C'; ctr < 5; ctr++)
{
fscanf(Collections,"%[^,], %f %*c",name, & amount);
if(amount == 0)
{
fprintf(Report,"### No Collections for %s \n", location);
fprintf(Report,"total: \t 0.00\n");
}
fprintf(Report,"\n Name: %s \t Amount: %.2f \n",name, amount);
fscanf(Collections,"%c,",&code);
}
code == 'T';
while(code == 'T')
{
fprintf(Report,"Hello");
fscanf(Collections,"%f",& amount);
total += amount;
grand_total += total;
fprintf(Report,"Total: \t %.2f \n",& total);
fprintf(Report,"Grand Total of all Collections is: $ %.2f", grand_total);
fscanf(Collections,"%c" , & code);
}
fclose(Collections);
fclose(Report);
}
When I run the above program it displays the printf() statement and when I hit enter and it exits. Than I open my report.txt file and find the date tab location new line and all the names and costs up until the T. Once it gets to the 'T' it stops, I cant get it to go into the last while loop, read the total and print it to the file than repeat by checking the code again. The code after the T is a L so it should go back into the first while loop and read than write the date and location but it does not. Any ideas what I'm doing wrong?
Also if there's any better way you think I should be doing this please let me know.
Have you tries stepping in the debugger and observing the variable state while doing so?
This line:
fprintf(Report,"Total: \t %.2f \n",& total);
is certainly incorrect, %f does not expect a pointer.
If the expectation is that code == 'T'; will force it to enter the loop, you are mistaken, code = 'T'; would work.
Similarly in this loop:
for(code == 'C'; ctr < 5; ctr++)
The initialising expression shpuld be code = 'C'
Try setting your compiler warning level to \W4 and \Wx (all warnings are errors), then the compiler may help you spot such errors.

Resources