All content of file get duplicated while modifying a specific entry - c

This code read/write data to/from binary file. Here modify() will take input from user, search for it in the file. If found, will prompt user to give new entry and the older entry would be replaced.
The question is, in modify() after fwrite() if I break the while loop then everything would be fine but, if I don't then the entry would still be modified but along with that the content of the file would be duplicated, why so ?
As in the beginning there are no duplicate entries in the file. So what I expect is, that even if I don't use break the loop should go on and finally terminate when whole file has been read. Here, the if(strcmp(e.name,user)==0) would only be true for one entry therefore the control should enter only once in this if block. Then how the entries are getting duplicated ?
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void add(FILE *);
void list(FILE *);
void modify(FILE *);
struct emp
{
char name[20];
int id;
float sal;
}e;
void add(FILE *f)
{
char *p=NULL;
printf("\nEnter name id sal\n");
scanf(" %s %d %f", e.name,&e.id,&e.sal);
fseek(f,0,SEEK_END);
if((fwrite(&e,sizeof(struct emp),1,f))==1)
{
printf("\nAdded Successfully\n");
}
else
{
printf("\nError wrting to file in ADD func\n");
}
}
void list(FILE *f)
{
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)>0)
{
printf("\nRead %s %d %f\n",e.name,e.id,e.sal);
}
}
void modify(FILE *f)
{
char user[20];
char *p=NULL;
printf("\nEnter name to modify\n");
scanf(" %s", user);
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)==1)
{
//printf("\n --------------- %s %d %f\n",e.name,e.id,e.sal);
if(strcmp(e.name,user)==0)
{
//fseek(f,-sizeof(struct emp),SEEK_CUR);
printf("\nEnter new name id salary\n");
scanf(" %s %d %f", e.name,&e.id,&e.sal);
fseek(f,-sizeof(struct emp),SEEK_CUR);
if(fwrite(&e,sizeof(struct emp),1,f)==1)
{
printf("\nModified successfull!!\n");
//break;
}
else
{
printf("\nError while modifying\n");
}
}
else
{
printf("\n\nstring not matched\n\n");
}
}
}
int main()
{
char val='T';
FILE *fp=NULL;
if((fp=fopen("database.dat","rb+"))==NULL)
{
if((fp=fopen("database.dat","wb+"))==NULL)
{
printf("\nError opening file in wb+ mode\n");
exit(0);
}
}
do
{
printf("\nEnter a to add, l to list, d to delete, m to modify and e to exit\n");
scanf(" %c", &val);
switch(val)
{
case 'a':
add(fp);
break;
case 'l':
list(fp);
break;
case 'm':
modify(fp);
break;
case 'd':
// del(fp);
break;
case 'e':
fclose(fp);
exit(0);
break;
default:
printf("\nInvalid Input\n");
break;
}
}
while(1);
}

I think it's a problem between fread() and fwrite().
After you use fwrite() to modify the emp, you continue the while loop without using fseek().
In fact, before, you used fseek() to go back and it was OK.
Now you have to place another fseek() which doesn't move, like this:
fseek(f, 0, SEEK_CUR);
Now you can remove the break and your Modify() function would seems like this:
void modify(FILE *f)
{
char user[20];
printf("\nEnter name to modify\n");
scanf("%s",user);
fflush(stdin);
rewind(f);
while(fread(&e,sizeof(struct emp),1,f)==1)
{
if(strcmp(e.name,user)==0)
{
printf("\nEnter new name id salary\n");
scanf("%s %d %f",e.name,&e.id,&e.sal);
fflush(stdin);
fseek(f,-sizeof(struct emp),SEEK_CUR);
if(fwrite(&e,sizeof(struct emp),1,f)==1)
{
printf("\nModified successfull!!\n");
//break; //This can be removed
fseek(f, 0, SEEK_CUR); //Place this here
}
else
{
printf("\nError while modifying\n");
}
}
else
{
printf("\n\nstring not matched\n\n");
}
}
}

Related

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.

Problem on reading a binary file using fread function

I am tasked to create an inventory program that stores data using structure and save the data into a binary file. The program should then be able to load the data i.e. the structure elements from the binary file. I am able to save the input data to a binary file using the fwrite function; however, I am having a problem in loading the file to the program using the fread function.
I already looked for similar problems but I can't find a similar case wherein the fread is used to pass the structure elements saved to the structure variable in the program.
This is the code for my structure
struct details {
char name[30];
double price;
int code;
int qty;
};
details item[SIZE];
Function in adding an item to the inventory
int AddItem(int n){
details inputitem;
printheader();
printf("Item Name: ");
scanf("%s", inputitem.name); //check %[^\n]
printf("\nItem Price: ");
scanf("%lf", &inputitem.price);
printf("\nItem Code: ");
scanf("%d", &inputitem.code);
printf("\nQuantity: ");
scanf("%d", &inputitem.qty);
printf("\nItem Added! The ID of the item is %d.\n", n+1);
item[n] = inputitem;
}
Function in displaying the inventory
int DisplayInventory(int n){
printheader();
printf("ID | NAME | CODE | QUANTITY | PRICE \n");
printf("------------------------------------------------------------\n");
for(int i=0; i<n; i++){
printf("%d %-18s %-10d %-10d %-10lf \n",i+1,item[i].name,item[i].code,item[i].qty,item[i].price);
}
}
Function in saving to a binary file
int SaveFile(int n){
FILE *fp;
fp=fopen("C:\\Users\\Royce\\Documents\\CPEPROG2 Goden Final Project\\Inventory.txt","wb");
if(!fp) {
printf("Cannot open file.\n");
system("pause");
exit(1);
}
for(int i=0; i<n; i++){
fwrite(&item[i], sizeof(struct details), 1, fp);
}
fclose(fp);
printf("File is saved!\n");
}
Function in loading the binary file
int LoadFile(int n){
FILE *fp;
fp=fopen("C:\\Users\\Royce\\Documents\\CPEPROG2 Goden Final Project\\Inventory.txt","rb");
if(!fp) {
printf("Cannot open file.\n");
system("pause");
exit(1);
}
struct details inputitem;
int i = 0;
while(fread(&inputitem, sizeof(struct details),1, fp)){
item[i] = inputitem;
i++;
/* printf("%d %-18s %-10d %-10d %-10lf \n",i+1,item[i].name,item[i].code,item[i].qty,item[i].price); */
}
fclose(fp);
printf("File is loaded!\n");
}
I expect the program to show in the DisplayInventory function the details of the structure saved in the binary file. However, nothing shows up at all.
When i try to print the structure in the LoadFile function (using the commented line), all variables show 0.
EDIT
Main Function
int main (){
int choice; //gets the choice of user from the menu
bool condition = 1; //loops the menu
//details item[50];
int count=0; //counts the number of items in the inventory
do{
printheader(); //prints the title of the program
printmenu(); //prints the menu (list of commands)
scanf("%d", &choice);
switch(choice){
case 1: system("cls");
AddItem(count);
count++;
system("PAUSE");
system("cls");
break;
case 2: system("cls");
//EditItem();
system("PAUSE");
system("cls");
break;
case 3: system("cls");
//DeleteItem();
system("PAUSE");
system("cls");
break;
case 4: system("cls");
//ViewItem();
system("PAUSE");
system("cls");
break;
case 5: system("cls");
DisplayInventory(count);
system("PAUSE");
system("cls");
break;
case 6: system("cls");
SaveFile(count);
system("PAUSE");
system("cls");
break;
case 7: system("cls");
LoadFile(count);
system("PAUSE");
system("cls");
break;
case 8: printf("\nThank you!");
exit(0);
break;
default: printf("\nInvalid Input!\n");
getch();
system("cls");
}
}while(condition = 1);
return 0;
}
The program never increments the 'count' variable, so when 'DisplayInventory' is called the value is always 0 and nothing is displayed :
return the i variable in 'LoadFile()' and assign it to the 'count' variable in the main() scope :
in LoadFile :
...
printf("File is loaded!\n");
return i;
}
in main :
...
case 7: system("cls");
count = LoadFile(count);
system("PAUSE");
system("cls");
Note that the 'n' argument in 'int LoadFile(int n)' is not used, you could remove it.

Using data inside a binary file in a conditional statement

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);

Creating a database for bank records

This is my code for a project I'm working on, my aim is to create a database where i can add edit and delete records. The program is compiling but very slowly and often crashes. I am a mere beginner and I cant figure out why this is happening. Maybe somebody can help me improve the code or point me in the right direction?
enter code here
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
void clearInput(void);
void listAll (void);
void deleteAccount(void);
void addNewAccount(void);
void modifyAccount(void);
int prompt(void);
struct account{
int number;
char lastname[15];
char firstname[15];
float balance;
struct account*next;
};
struct account *firsta, *currenta, *newa;
int anum = 0;
int main()
{
FILE *datafile;
char *filename="studentdatabase.txt";
char ch;
firsta=NULL;
datafile=fopen(filename, "r");
if (datafile) /*assume doesnt exist otherwise*/
{
firsta=(struct account*)malloc(sizeof(struct account));
currenta=firsta;
while (1)
{
newa=(struct account*)malloc(sizeof(struct account));
fread(currenta, sizeof(struct account),1,datafile);
if (currenta->next==NULL)
break;
currenta->next=newa;
}
fclose(datafile);
anum=currenta->number;
}
do
{
clearInput();
puts("\nA - Add a new account");
puts("D - Delete account");
puts("L - List all accounts");
puts("M - Modify account");
puts("Q - Quit this program\n");
printf("\tYour Choice:");
ch=getchar();
ch=toupper(ch);
switch(ch)
{
case 'A':
puts("Add new account\n");
clearInput();
addNewAccount();
break;
case 'D':
puts("Delete account\n");
deleteAccount();
break;
case 'L':
puts("List all accounts\n");
listAll();
break;
case 'M':
puts("Modify an account\n");
modifyAccount();
break;
case 'Q':
puts ("Quit\n");
default:
break;
}
}
while(ch!='Q');
/*Save the records to disc*/
currenta=firsta;
if(currenta==NULL)
return(0); /*No data to write - End of Program*/
datafile=fopen(filename,"w");
if (datafile=NULL)
{
printf("Error writing to %s\n", filename);
return(1);
}
/*write each record to disc*/
while(currenta!=NULL)
{
fwrite(currenta, sizeof(struct account),1,datafile);
currenta=currenta->next;
}
fclose(datafile);
return(0);
}
/*This function clears any text from the input stream*/
void clearInput(void)
{
fflush(stdin);
}
void addNewAccount(void)
{
newa=(struct account*)malloc(sizeof(struct account));
/*Check to see if this is the first record, if so then
itialize all the pointers to this, first ftrusture in
the database*/
if(firsta==NULL)
firsta=currenta=newa;
/*Otherwise you must find the end of the structure list
(easily spotted by the NULL pointer) and add on the new
structure you just allocated memory for*/
else
{
currenta=firsta; /*makes the first current*/
/*loop throught all records*/
while(currenta->next!=NULL)
currenta=currenta->next;
/*last record found*/
currenta->next=newa; /*save the address of new*/
currenta=newa; /*makes current new*/
}
/*now you just fill in the new structure*/
anum++;
printf("%27s:%5i\n","Account number", anum);
currenta->number=anum;
printf("%27s:","Enter customer's lastname");
gets(currenta->lastname);
printf("%27s:","Enter firstname");
gets(currenta->firstname);
printf("%27f:€","Enter account balance");
scanf("%f", &currenta->balance);
/*Finally cap the new record with a NULL pointer so
that you know its the last record*/
currenta->next=NULL;
}
void listAll(void)
{
if (firsta==NULL)
puts("There are no records to print out");
else
{
printf("%6s %-15s %-15s €%8.2f\n",
currenta->number,
currenta->lastname,
currenta->firstname,
currenta->balance);
}
while ((currenta=currenta->next) !=NULL);
}
void deleteAccount(void)
{
int record;
struct account *previousa;
if(firsta==NULL)
{
puts("There are no records to delete");
return;
}
listAll();
/*Shows all record first*/
printf("Enter account number to delete: ");
scanf("%d",&record);
currenta=firsta;
while(currenta!=NULL)
{
{
if(currenta->number==record)
{
if(currenta==firsta) /*special condition*/
firsta=currenta->next;
else
previousa->next=currenta->next;
free(currenta);
printf("Account %d deleted! \n", -record);
return;
}
previousa=currenta;
currenta=currenta->next;
}
}
printf("Account %d was not found!\n", record);
puts("Nothing deleted.");
}
void modifyAccount(void)
{
int record;
if (firsta==NULL)
{
puts("There are no records to modify!");
return;
}
listAll(); /*Show all records first*/
printf("Enter account number to modify or change: ");
scanf("%d",&record);
currenta=firsta;
while (currenta!=NULL)
{
if(currenta->number==record)
{
printf("Account €%d:\n", currenta->number);
printf("Last name: %s\n", currenta->lastname);
if (prompt())
gets (currenta->lastname);
printf("firstname %s \n", currenta->firstname);
if (prompt())
gets(currenta->firstname);
printf("Balance %8.2f\n", currenta->balance);
if (prompt())
scanf("%f", &currenta->balance);
return;
}
else
{
currenta=currenta->next;
}
}
printf("Account %d was not found!\n", record);
}
int prompt(void)
{
char ch;
clearInput();
printf("Update?");
ch=getchar();
ch=toupper(ch);
clearInput();
if(ch=='Y')
{
printf("Enter new. ");
return(1);
}
else return(0);
}
Your input loop in the start looks a bit odd to me.
while (1)
{
newa=(struct account*)malloc(sizeof(struct account));
fread(currenta, sizeof(struct account),1,datafile);
if (currenta->next==NULL)
break;
currenta->next=newa;
}
I understand that you are relying on the fact that when you wrote out the list the last structure written should have had the 'next' field set to NULL as your end marker, but I would suggest you might want find a cleaner way to check for end. This will also have a small memory leak since you allocate newa but then break on the last read, so that last newa is never used.
Also, the load routine results in the first record in the list being an empty record because you allocate firsta, set currenta to it, then allocate newa for the first read and set it to the next of the empty currenta.
After loading, though you will only ever have 1 record. Notice that you are not reading into newa you read into currenta
fread(currenta, sizeof(struct account),1,datafile);
Your attempt to save the data also has an issue, you have one of the classic typo errors:
datafile=fopen(filename,"w");
if (datafile=NULL)
^^^
you are reassigning NULL to the datafile variable, you need == here.
You appear to assume through out the code that currenta, which is global, is in a known state. For example, in the listAll function, your code is not setting currenta before printing out a record. Note also listAll is not looping and printing all records, you print only whatever currentA is then move that variable to being NULL.
I would suggest you keep only firsta as a global to locate the head of the list, but everywhere else you use local variables and set them up correctly.
As previously mentiond, your printf statements need to match their data types. That can cause failures.
One problem is in the printf:
printf("%6s %-15s %-15s €%8.2f\n",
currenta->number,...
Here you are printing an integer currenta->number using %s format specifier, use %d instead.
Another problem is when you are trying to print the list:
printf(...);
while ((currenta=currenta->next) !=NULL);
This is not how you print the list. You need to have a printf as the body of the while loop:
while (currenta != NULL) {
printf(...);
currenta = currenta->next;
}

Resources