Using data inside a binary file in a conditional statement - c

It's my first time asking here, so I'm sorry in advance if my post is a bit messy. I'm a freshman and my finals is to make an atm program.
My program uses switch statements for the options: the first one asks the user for their info, (account number, account name, PIN, initial deposit), while the second one is for the actual transactions: Balance check, Deposit and Withdrawal. Before you could do any one of those options, of course I'll have to check if the info (in this case the account number and PIN) matches the ones in my file.
The file is in binary. My problem is that my code for reading the file works fine if i want to display the contents of my file (all the data entries that I populated the file with are shown), but when i want to use the contents of the file (searching inside the file for a match of the user inputted account number) it only reads the first line of the file, thus only the first data entry works, while the one's after that are not read.
My question is, what am i doing wrong in my code? its confusing because if I change my code to display the contents it shows everything, meaning it reads the whole file. but when i want to search the file using a conditional statement, only the first data entry gets read. Thank you very much for your time
tldr: can't use data in file for conditionals (verify the data inside the file, cuz my code doesn't read it whole apparently, except for the first entry)
but if i print the contents it reads it fully
my outputs
1.My data entries
data entries
2.Entering the Account no. of the 1st one (desired output)
desired output
3.Entering The account no. of the 2nd one (Problem part)
problem
my main code
#include<stdio.h>
#include<conio.h>
#include<ctype.h>
#include<stdlib.h>
#include<string.h>
#include<process.h>
struct account
{
int no;
char name[100];
int pin;
float id;
};
main()
{
FILE *fptr;
fptr = fopen("accrec.dat","ab");
if (fptr == NULL)
{
printf("File does not exists \n");
return 0;
}
system("cls");
struct account accrec;
int i,tpin[4];
char step1,ch;
printf("\t\tWelcome to Banking System\n\t");
printf("\nA.Open an Account\n");
printf("\nB.Bank Transaction\n");
printf("\nC.exit\n");
scanf("%c",&step1);
switch (step1)
{
case 'A':
printf("Open a New Account\n");
printf("\nEnter the following information\n");
printf(" \n5-digit Account number:");
scanf("%d",&accrec.no);
getchar();
printf("\nAccount Name:");
scanf("%[^\n]s",&accrec.name);
printf("\n4-digit Account PIN:");
/*for(i=0;i<4;i++)
{
ch = getch();
tpin[4] = ch;
ch = '*' ;
printf("%c",ch);
}mask works but does not allow PIN saving */
scanf("%d",&accrec.pin);
printf("\nInitial deposit:");
scanf("%f",&accrec.id);
fwrite(&accrec,sizeof(struct account),1,fptr);
fclose(fptr);
break;
case 'B':
{
fptr = fopen("accrec.dat","rb");
int choice;
int accno = 0;
printf("Enter Your Account no.");
scanf("%d",&accno);
while (fread(&accrec,sizeof(account),1,fptr)!=NULL)
{
if(accno == accrec.no)
{
printf("\tWelcome to PUPQC Banking System\n");
printf("1.Balance Inquiry\n");
printf("2.Deposit\n");
printf("3.Withdrawal\n");
printf("4.quit\n");
scanf("%d",&choice);
}
else
{
printf("account doesn't exist\n");
exit(1);
}
fclose(fptr);
switch (choice)
{
case 1:
printf("BALANCE INQUIRY\n");
printf("Current Balance:");
fptr = fopen("accrec.dat","rb");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
printf("Account No: %d\n",accrec.no);
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL);
{
printf("Initial Deposit is %0.2f\n",accrec.id);
}
printf("%d\n",&accrec.id);
break;
case 2:
float dv;
printf("DEPOSIT\n");
printf("Current Balance:");
fptr = fopen("accrec.dat","rb");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL);
{
printf("%0.2f\n",accrec.id);
}
printf("Enter amount to deposit:\n");
printf("Deposit Value:");
scanf("%0.2f",&dv);
accrec.id = accrec.id + dv;
fwrite(&accrec,sizeof(struct account),1,fptr);
fclose(fptr);
break;
case 3:
float wv;
printf("WITHDRAWAL\n");
printf("Current Balance:");
fptr = fopen("accrec.dat","rb+");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL);
{
printf("%0.2f\n",accrec.id);
}
printf("Enter amount to withdraw:\n");
printf("Withdrawal Value:");
scanf("%0.2f",wv);
accrec.id = accrec.id - wv;
fwrite(&accrec,sizeof(struct account),1,fptr);
fclose(fptr);
break;
case 4:
printf("thank you for your patronage \n");
return 0;
break;
default:
printf("error 404");
break;
}
}
}
break;
case 'C':
printf("Thank you! Have a good day");
return 0;
break;
case 'D':
fptr = fopen("accrec.dat","rb");
if (fptr == NULL)
{
printf("File Cant be read");
exit(1);
}
printf("Data From file\n");
while(fread(&accrec,sizeof(struct account),1,fptr)!=NULL)
printf("\n acc.no is %d\n acc.name is %s\n PIN %d\n Initial Deposit is %0.2f\n ",accrec.no,accrec.name,accrec.pin,accrec.id);
fclose(fptr);
getch();
break;
default:
printf("invalid input! please select form the options given\n");
}
}
my structure
struct account
{
int no;
char name[100];
int pin;
float id;
};
code for finding a match of account number in my file
(the part i'm having trouble with)
fptr = fopen("accrec.dat","rb");
int choice;
int accno = 0;
printf("Enter Your Account no.");
scanf("%d",&accno);
while (fread(&accrec,sizeof(account),1,fptr)!=NULL)
{
if (accno == accrec.no)
{
printf("\tWelcome to Banking System\n");
printf("1.Balance Inquiry\n");
printf("2.Deposit\n");
printf("3.Withdrawal\n");
printf("4.quit\n");
scanf("%d",&choice);
}
else
{
printf("account doesn't exist\n");
exit(1);
}
}
fclose(fptr);
The expected output is that my conditional statement works properly and reads my whole file for matches.

try to change the exit(1) to continue;, the exit(1) will make your program quit the while loop and exit the program immediately whenever accno != accrec.no.
in fact, you don't need the else statement inside the while loop, you should put it outside the while loop. for example:
scanf("%d",&accno);
boolean found = false;
while (fread(&accrec,sizeof(account),1,fptr)!=NULL)
{
if (accno == accrec.no)
{
found = true;
scanf("%d",&acpin);*/
printf("\tWelcome to Banking System\n");
printf("1.Balance Inquiry\n");
printf("2.Deposit\n");
printf("3.Withdrawal\n");
printf("4.quit\n");
scanf("%d",&choice);
}
}
if (!found) {
printf("account doesn't exist\n");
}
fclose(fptr);

Related

I can't get my code to break out of the switch statement

I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
I can't get my delete record function to break out of the switch case or even give me an error when the record doesn't exist. Could someone please tell me why this is?
Any help is much appreciated!
void delete_record();
void displayContent();
struct Update
{
char studentName[50];
char studentID [50];
char emailID[100];
char courseID[5];
char grade[50];
} update2;
int main ()
{
int num;
do
{
printf("1. Delete a record for the specific name\n");
printf("2. Display Content of File\n");
printf("6. Exit\n");
switch(num)
{
case 1:
printf("this is a test\n");
delete_record();
break;
//displayContent();
//printf("this is a test 2\n");
case 2:
printf("\n\nDiplaying Contents of File\n\n");
displayContent();
default:
printf("Give me a break!\n");
break;
}
scanf("%d", &num);
} while (num != 6);
return 0;
}
void delete_record()
{
FILE *fp;
FILE *fp_tmp;
fp = fopen ("BINARY_FILE.txt", "w");
char studentsID[20];
printf("enter studentID to delete:");
scanf("%s",studentsID);
printf("is this a test?\n");
while(fread(&update2,sizeof(update2),1,fp))
{
printf("this is another test\n");
if(strcmp(update2.studentID,studentsID) != 0)
{
//printf("testing\n");
fwrite(&update2,sizeof(update2),1,fp);
}
else
{
printf("No student with that student ID\n");
}
}
printf("more tests\n");
fclose(fp);
return;
}
void displayContent()
{
char c;
// Open file
FILE *fp;
fp = fopen ("BINARY_FILE.txt", "r");
if (fp == NULL)
{
printf("File Has No Content\n");
exit(0);
}
// Read contents from file
c = fgetc(fp);
while (c != EOF)
{
printf ("%c", c);
c = fgetc(fp);
}
fclose(fp);
//return 0;
}
When using scanf to read from the keyboard you must remember
that all characters that you enter are written to the in-buffer,
this means that if you type in
42ENTER
The ENTER will also be present in the in-buffer, so next time you call scanf ENTER will still be in the buffer and then scanf returns 0 since the format specificier "%d" doesn't match.
The easiest way to handle input from keyboard in C and to avoid the hassle of scanf in-buffer by using fgets() to read from the keyboard, then use sscanf() to cherry pick from the buffer:
// always check return value from all runtime functions when possible
char buffer[128];
if (fgets(buffer,sizeof(buffer), stdin) != NULL)
{
if (sscanf(buffer, "%d", &num) == 1)
{
}
else {...}
}
else {...}

Switch Case is getting triggered by itself in C

I have a file student.txt and it has a content like
Name RollNo Address ...\n
Name RollNo Address ...\n
And I have written a function to search a Name in the file
it's menu driven and goes like
std student;
FILE *file = NULL;
int choice;
char name[20];
while (1)
{
printf("Enter the choice\n1.Insert\t2.Append\t3.Search\t4.Display: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
//insertion
break;
case 2:
// append
break;
case 3:
printf("Enter the student name to be searched: ");
scanf("%d", &name);
search(name, &file);
break;
case 4:
// display
break;
default:
exit(0);
break;
}
}
return 0;
search function is
void search(char ele[], FILE **fileptr)
{
*fileptr = freopen("student.txt", "r", *fileptr);
char line[100];
while (fgets(line, 100, *fileptr) != NULL)
{
if (strstr(line, ele) != NULL)
{
getchar();
printf("Congrats !!\n");
return;
}
}
printf("not found\n");
fclose(*fileptr);
}
But when i run this though has a filename matching filename it goes to an infinite loop and executes display function and triggers search function itself infinitely
It happens when the data is not taken in correctly using a correct format specifier.
In case 3, in the scanf function, use the format specifier
%s
instead of
%d
That will stop the infinite loop.

My basic trade program in C does not store any modifications when I close command prompt

#include<stdio.h>
int main() {
//After selling and buying i want it to modify this
struct music {
int srno;
char name[10];
int upperlimit;
int lowerlimit;
int avarn;
};
//Structure to maintain personal data
struct custormer {
int srno;
char name[5];
int upperlimit;
int lowerlimit;
int avarn;
};
FILE *f1;
int choice,amount,price;
int x,code,j=0;
struct music m1[] = {1,"Apple",100,98,10,2,"Valve",100,98,10,3,"Google",90,80,10,4,"Tesla",100,98,10};
struct music m2[10];
f1 = fopen("4.DAT","rb+");
if(f1==NULL)
{
printf("File does not exist!");
exit(0);
}
while(1)
{
printf("___________________________________\n");
printf("MENU\n");
printf("___________________________________\n");
printf("1) Stock Market\n");
printf("2) Buy\n");
printf("3) Personal Info\n");
printf("4) Sell\n");
printf("5) Exit\n");
printf("Enter choice:");
scanf("%d",&choice);
switch(choice)
{
case 1:
{
printf("Stock Market\n");
printf("___________________________________\n");
for(x=0;x<4;x++)
{
printf("%d\t %s\t %d\t %d\t %d\n",m1[x].srno,m1[x].name,m1[x].upperlimit,m1[x].lowerlimit,m1[x].avarn);
fwrite(&m1,sizeof(m1),1,f1);
}
break;
}
case 2:
{
printf("Enter code of Stock:");
scanf("%d",&code);
printf("Enter number of stocks:");
scanf("%d",&amount);
printf("Enter price:");
scanf("%d",&price);
rewind(f1);
for(x=0;x<4;x++)
{
if(price>m1[x].lowerlimit&&price<m1[x].upperlimit)
{
if(m1[x].srno==code)
{
printf("Trasaction Is Succesful\n");
m1[x].avarn = m1[x].avarn-amount;
fwrite(&m1,sizeof(m1),1,f1);
m2[j].srno = j+1;
strcpy(m2[j].name,m1[x].name);
m2[j].avarn = amount;
j++;
}
}
}
break;
}
case 3:
{
for(x=0;x<j;x++)
{
printf("%d\t %s\t %d\n ",m2[x].srno,m2[x].name,m2[x].avarn);
fseek ( f1, sizeof(m1), SEEK_CUR ) ;
fwrite ( &m2, sizeof(m2), 1, f1 ) ;
}
break;
}
case 4:
{
printf("Enter code of stock to sell:");
scanf("%d", &code);
printf("Enter amount to sell:");
scanf("%d",&amount);
printf("Enter price to sell:");
scanf("%d",&price);
for(x=0;x<4;x++)
{
if(price>m1[x].lowerlimit&&price<m1[x].upperlimit)
{
if(m1[x].srno==code)
{
printf("Transaction is Sucessful\n");
m1[x].avarn = m1[x].avarn+amount;
fwrite(&m1,sizeof(m1),1,f1);
}
}
}
break;
}
case 5:
{
printf("Thanks!");
exit(0);
}
default:
{
printf("Invalid input!");
exit(0);
break;
}
}
}
fclose(f1);
return 0;
}
The program will execute and run but it will not store any data that I add when I buy or sell stocks, I'm still learning file operations, can someone correct this program or tell me how to do it? I feel like the fwrite() function is maybe not taking in the values I'm giving it The program will execute and run but it will not store any data that I add when I buy or sell stocks, I'm still learning file operations, can someone correct this program or tell me how to do it? I feel like the fwrite() function is maybe not taking in the values I'm giving it
You are using the wrong operator for testing equality.
if(f1=NULL)
This statement will assign NULL to f1, which will then evaluate to false.
You should use if (f1 == NULL) to test if it's NULL. Or just simply if (f1).
Something else strange that you are doing is opening the file twice, leaking the first handle. You should close it first, or open it only once.
Also, you should pay attention to the open mode. Your second call will actually destroy the file's contents. Read the documentation.

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.

Loading a text file into a struct using C

I try to load the contents of a text file into a structure.
My idea looks like this:
I have two files, struct.h , main.c and a list.txt file .
in file struct.h :
struct analg {
char word[6];
char signature[6];
};
struct analg h[106];
FILE *fp;
In file main.c :
#include<stdio.h>
#include "struct.h"
void load() {
fp = fopen("list.txt", "r");
if(fp == NULL) {
printf("fail");
return 1;
}
else {
printf("file loaded!\n");
}
fclose(fp);
return;
}
void print() {
int i;
for(i=0; i<1000; i++) {
while(fgets(h[i].word, 6, fp)) {
printf("%s", h[i].word);
}
}
return;
}
int main () {
int choice;
do {
printf("choose L or P: ");
scanf("%s", &choice);
switch(choice) {
case 'l':
load();
printf("\n[l]oad - [p]rint\n");
break;
case 'p':
print();
printf("\n[l]oad - [p]rint\n");
break;
default:
break;
}
} while(choice!='q');
return;
}
In file list.txt :
throw
timer
tones
tower
trace
trade
tread
So I try to load the text file by pressing the "L" to the structure, and then when I press the 'p' will be displayed, but it is not!
In your code, I see there are 2 potential issues. The choice has to be a character to be switched based on l or p. You may have to add cases to handle the upper case also.
Another issue is that in load function, you are closing the file pointer. Hence, when you enter the print function fgets may not work as the fp is already closed.
To load your file into structure, the load has to be modified as
void load() {
fp = fopen("list.txt", "r");
if(fp == NULL) {
printf("fail");
return; // There was an error in original code as this was returning 1
}
do{
fgets(h[count++].word, 6, fp); // Count is a global variable - no. of elements read
}while(!feof(fp));
printf("file loaded!\n");
fclose(fp);
return;
}
The corresponding print function would become
void print(){
int i;
printf("Inside print\n");
for(i=0; i < count; i++) {
printf("%s", h[i].word);
}
return;
}
the main function would be,
int main (){
char choice;
do{
printf("choose L or P: ");
scanf("%c", &choice); //Only character is read and hence, %s is not required
switch(choice){
case 'l':
load();
printf("\n[l]oad - [p]rint\n");
break;
case 'p':
print();
printf("\n[l]oad - [p]rint\n");
break;
default:
case 'q':
break;
}
} while(choice !='q');
return 0;
}
One last point. In the scanf statement if scanf("%s", &choice); is employed, then a runtime check error is generated when main exits, with a message that stack is corrupted around the variable choice.
I'll comment up what your code is doing:
void load() {
fp = fopen("list.txt", "r"); // opens the file for reading
if(fp == NULL) {
printf("fail"); // if the file couldn't be opened, return an error
return 1; // (aside: a void function can't return an int)
}
else {
printf("file loaded!\n"); // tell the user that the file was opened
}
fclose(fp); // close the file, having read nothing from it
return;
}
At no point do you read anything from the file. What you have in memory will therefore have no relation to whatever you have on disk.
C has no built-in means for serialising and deserialising structs so what you need to do is define a formal grammar for your file on disk and write code that can parse that grammar into your structs.

Resources