How to delete the record from file - c

# include <stdio.h>
# include <conio.h>
# include <string.h>
# include <stdlib.h>
struct dnode{
char dlname[20],
dfname[20],
dtel[15];
struct dnode *dnext;
};
int dmenu(); //main menu
void dadd(); //add to list
void dfind(); //search from the list
void dedit(); //edit the record
void ddel(); //delete from the list
void ddisp(); //display all
dnode* sort(dnode* head_node);
typedef struct dnode node;
node *dstart, *dtemp;
int dmenu()
{
int dch;
int i,j,n;
printf(" TELEPHONE DIRECTORY ");
printf(" =================== ");
printf(" \n1. Add ");
printf(" \n2. Find ");
printf(" \n3. Sort ");
printf(" \n4. Delete ");
printf(" \n5. Display All ");
printf(" \n6. EXIT ");
printf(" \nEnter your choice(1-6):");
scanf("%d", &dch);
return dch;
}
void dadd()
{
FILE *fp;
fp=fopen("record.txt","a");
node *dptr,*dprev;
dtemp=(node *)malloc(sizeof(node));
printf("First name: ");
scanf("%s", dtemp->dfname);
printf("Last name:");
scanf("%s", dtemp->dlname);
printf("Telephone No.: ");
scanf("%s", dtemp->dtel);
dtemp->dnext=NULL;
if(dstart==NULL) dstart=dtemp;
else {
dprev=dptr=dstart;
while(strcmp(dtemp->dfname,dptr->dfname)>0){
dprev=dptr;
dptr= dptr->dnext;
if (dptr == NULL) break;
}
if(dptr==dprev) {
dtemp->dnext=dstart;
dstart=dtemp;
}
else if(dptr==NULL)
dprev->dnext=dtemp;
else {
dtemp->dnext=dptr;
dprev->dnext=dtemp;
}
}
fprintf(fp,"%20s %20s %s\n",dtemp->dfname,dtemp->dlname,dtemp->dtel);
fclose(fp);
}
void dfind()
{
FILE *fp;
node *dptr;
char dstr[20];
fp=fopen("record.txt","r");
if(dstart==NULL){
printf("\n\t\t\tTelephone Directory is Empty....\n");
getch();
return;
}
printf("First Name to Find : ");
scanf("%s",dstr);
dptr=dstart;
while(strcmp(dptr->dfname,dstr)!=0)
{
dptr= dptr->dnext;
if (dptr == NULL) break;
}
if(dptr!=NULL) {
printf("First Name : %s\n",dptr->dfname);
printf("Last Name : %s\n",dptr->dlname);
printf("Phone Number : %s\n",dptr->dtel);
}
else {
printf("No Matching Records Found .......\n");
}
fclose(fp);
getch();
}
This is my sorting function, how can i sort the record in file?
dnode* sort(dnode* head_node)
{
dnode *prev, *curr = head_node;
int i, list_size = 0;
/* Determine the size first */
while (curr != NULL)
{
list_size++;
curr = curr->dnext;
}
/* sorting */
for (i = 1; i < list_size; i++)
{
curr = head_node;
while (curr->dnext != NULL)
{
if (strcmp(curr->dfname, curr->dnext->dfname) > 0)
{
dnode* next_node = curr->dnext;
curr->dnext = next_node->dnext;
next_node->dnext = curr;
if (curr == head_node)
head_node = next_node;
else
prev->dnext = next_node;
curr = next_node;
}
prev= curr;
curr = curr->dnext;
}
}
return head_node;
}
Here is my delete function, anyone can help me to solve the delete record in a file?
void ddel()
{
node *dptr,*dprev,*dtemp;
char dstr[20],dyn='n';
struct dnode record;
if(dstart==NULL) {
printf("\n\t\t\tTelephone Directory is Empty....\n");
getch();
return;
}
printf("First Name to Delete : ");
scanf("%s",&dstr);
dprev=dptr=dstart;
while (strcmp(dptr->dfname,dstr)!=0)
{
dprev=dptr;
dptr= dptr->dnext;
if (dptr == NULL)
break;
}
if(dptr!=NULL){
printf("\nDeleting Record.....Confirm [y/n]: ");
dyn=getch();
printf("\n\n---------------------------------------------------------");
printf("\nFirst Name : %s\n",dptr->dfname);
printf("Last Name : %s\n",dptr->dlname);
printf("Phone Number : %s\n",dptr->dtel);
printf("---------------------------------------------------------");
if(dyn=='y') {
if (dptr==dstart) {
dtemp=dstart->dnext;
free(dstart);
dstart=dtemp;
}
else {
dtemp=dptr->dnext;
free(dptr);
dprev->dnext=dtemp;
}
printf("\n\n1 Record Deleted....");
}
else
printf("\n\nRecord not Deleted....");
}
else {
printf("\nNo Matching Records Found .......");
}
getch();
}
void ddisp()
{
FILE *fp;
struct dnode rec;
fp=fopen("record.txt","r");
node *dptr;
if(dstart==NULL) {
printf("\n\t\t\tTelephone Directory is Empty....\n");
getch();
return;
}
printf("\t\t------------------------------\n");
for(dptr=dstart; dptr!=NULL; dptr=dptr->dnext) {
printf("\t\tFirst name: %s", dptr->dfname);
printf("\n\t\tLast name:%s", dptr->dlname);
printf("\n\t\tTelephone No.: %s", dptr->dtel);
printf("\n\t\t------------------------------\n");
}
fclose(fp);
getch();
}
int main()
{
int dch;
int i,j,n;
dstart=(node *)malloc(sizeof(node));
dstart=NULL;
do{
dch=dmenu();
switch(dch) {
case 1: dadd();
break;
case 2: dfind();
break;
case 3: dstart = sort(dstart);;
break;
case 4: ddel();
break;
case 5: ddisp();
break;
}
}while(dch!=6);
}
I have done this code but i can not delete and sorting the record in record.txt file.

To sort a file: read all the records, sort them in memory, then write all of them in the refreshed file (open it in w mode to reset it to an empty file). If there is too many records to handle them in memory you may need to find some alternative (an index would be more appropriate).
To delete: you can't delete something in a file, you need to rewrite most of the file. If there is not so much record, read all of them, remove the one from the memory structure and then rewrite a fresh file. You may find some alternative in the case of too many records.

Ask yourself some questions first on how is your program supposed to deal with adding/storing/searching and deleting records. Only after this start to modify it.
E.g. do you wan to process your data on disk, or in memory? If you prefer to process the phone list in memory in the form of a list – when are you going to synchronize what you have in memory with what you have on disk? As for now it is not clear from your code when you have to open of close the data file, or if our advice should concentrate on deleting/sorting records in memory or on disk.
Without even a sketchy design you have too many ways to change your program.

Related

C - Crashing when using Realloc on a Pointer inside a Struct

I've been writing a small program that will allow the user to read a file, create a small "database" and the ability to create / delete entries, etc. When I try to use the
realloc()
function, it crashes.
Not sure if I am doing something wrong, probably am though, since I'm rather new to C.
So, I try to do it this way:
StudentDB database;
//More code in between, that does include malloc()
database->students = realloc(database->students, (database->numberOfStudents + 1) * sizeof(Student));
//It crashes when it gets to that part.
What I am trying to do is use the realloc() function for a pointer that's inside a struct.
This is the entire program so far:
#include <stdio.h>
#include <stdlib.h>
typedef struct Lesson {
char *name;
int semester;
float grade;
} Lesson;
typedef struct Student {
char *name;
char *surname;
int id;
int numberOfLessons;
Lesson *lesson;
} Student;
typedef struct Database {
int numberOfStudents;
Student *student;
} StudentDB;
static int maxNameSize = 100;
static int autoclear = 1;
void addStudent(FILE *studentFile, StudentDB *database) {
database->numberOfStudents++;
printf("\nAdded +1 to number of students");
database->student = realloc(&database->student, 10);
//
// printf("Name of the student: ");
// scanf("%s", database.student[database.numberOfStudents].name);
}
void clear() {
if(autoclear) {
system("cls");
}
}
Lesson getNextLesson(FILE *studentFile) {
Lesson lesson;
lesson.name = malloc(maxNameSize * sizeof(char));
if(!lesson.name) { printf("Memory Allocation has failed. Exiting the program!"); exit(0); }
fscanf(studentFile, "%s", lesson.name);
fscanf(studentFile, "%d", &lesson.semester);
fscanf(studentFile, "%f", &lesson.grade);
printf("\n\t%s %d || %.2f\n", lesson.name, lesson.semester, lesson.grade);
return lesson;
}
Student getNextStudent(FILE *studentFile) {
Student student;
student.name = malloc(maxNameSize * sizeof(char));
if(!student.name) { printf("Memory Allocation has failed. Exiting the program!"); exit(0); }
fscanf(studentFile, "%s", student.name);
student.surname = malloc(maxNameSize * sizeof(char));
if(!student.surname) { printf("Memory Allocation has failed. Exiting the program!"); exit(0); }
fscanf(studentFile, "%s", student.surname);
fscanf(studentFile, "%d", &student.id);
fscanf(studentFile, "%d", &student.numberOfLessons);
printf("%d || %s %s || %d\n", student.id, student.name, student.surname, student.numberOfLessons);
int lesson;
student.lesson = malloc(student.numberOfLessons * sizeof(Lesson));
for(lesson = 0; lesson < student.numberOfLessons; lesson++) {
student.lesson[lesson] = getNextLesson(studentFile);
}
return student;
}
void loadStudents() {
}
void run(FILE *studentFile, StudentDB *database) {
int answer;
do {
clear();
answer = menu();
switch(answer) {
case 1: {
break;
}
case 2: {
break;
}
case 3: {
addStudent(studentFile, &database);
break;
}
case 4: {
break;
}
}
} while(answer < 0 || answer > 9);
}
int menu() {
int answer;
printf("1. Load students records from file\n");
printf("2. Save students records to file\n");
printf("3. Add a student record\n");
printf("4. Delete a student record by student id\n");
printf("5. Display a student record by student id\n");
printf("6. Display a student record by student surname\n");
printf("7. Display all student records\n");
printf("8. Find the lesson average for all students\n");
printf("9. Exit\n");
printf("Enter the number of the thing you would like to do: ");
// scanf("%d", &answer);
return 3;
}
void programInfo() {
printf("\n\n====================================================\n\tProgram Info\n\n This program was created by KKosyfarinis\n\n KKosyfarinis#uth.gr\n====================================================\n\n");
}
void readData(FILE *studentFile, StudentDB *db) {
int i;
printf("Running the loop\n");
for(i = 0; i < db->numberOfStudents; i++) {
printf("=====================\n\n\tStudent #%d\n", i);
db->student[i] = getNextStudent(studentFile);
printf("\n\tCompleted\n\n=====================\n");
}
clear();
}
void saveStudents() {
}
void main() {
system("color 02");
system("#echo off");
FILE *studentFile;
StudentDB database;
studentFile = fopen("students.txt", "r+w");
int numberOfStudents;
//Set the number of students
fscanf(studentFile, "%d", &database.numberOfStudents);
//Prints the number of students
printf("Number of students: %d\n", database.numberOfStudents);
//Set the memory allocation
database.student = malloc(database.numberOfStudents * sizeof(Student));
if(!database.student) {
printf("The memory allocation has failed. Exiting the program!");
exit(0);
}
//Read the students
readData(studentFile, &database);
programInfo();
run(studentFile, &database);
}
Thanks in advance for any help!
You're two code blocks have differing lines. One of which (the larger one) is incorrect. You are passing in a dereference to the student pointer? That's not needed, just pass the pointer itself.
database->student = realloc(&database->student, 10);
Should be:
database->student = realloc(database->student, 10);
You are also not passing in a realistic size, but your first code sample was. Does the following line not work?
database->students = realloc(database->students, (database->numberOfStudents + 1) * sizeof(Student));
That was just copied from your question. I'm confused as to what you have/have not tried and which one gives you the error.
Also, in the future provide more of a minimal example that still produces the error. There's also a chance you would figure out the issue while stripping the code down.
What with this line ?
addStudent(studentFile, &database);
in run function ? Where pointer to local variable is taken and passed to addStudent function
void run(FILE *studentFile, StudentDB *database) {
...
case 3: {
addStudent(studentFile, &database); // <-- get pointer to local variable
i think this code cannot work even with Nick's changes without this modification
addStudent(studentFile, database);

Removing nodes from middle of Linked List and infinite loop in C

I'm trying to create a linked list structure in C to allow a user to enter a list of direct debits with a description, then allow the user to select and delete any node. The solution I got from many sources, while researching, isn't working. No matter which node I choose, the latest one is always deleted.
Can anyone tell me where the problem in my code is?
It's also started throwing infinite loops of one node when printining the entire list
#define true 1
#define false 0
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
struct Banknode {
float debit;
char description[100];
struct Banknode *next;
}Banknode;
struct Banknode *latestPtr = NULL;
int isEmpty(void);
void add(float fig, char info[100]);
float rmv(int n);
void allList();
void showMenu();
int main()
{
latestPtr = NULL;
int choice;
float deb;
char info[100];
int n;
//MENU
printf("\nWelcome to your DirectDebit management system");
printf("\nPlease select an option:");
printf("\n1. View Latest DirectDebit");
printf("\n2. View all DirectDebits");
printf("\n3. Add a DirectDebit");
printf("\n4. Remove a DirectDebit");
printf("\n5. Show menu");
printf("\n6. Exit\n");
while(choice != 6)
{
scanf("\n%d", &choice);
switch(choice)
{
case 1:
{
if(!isEmpty())
{
printf("\nThe latest DirectDebit is: \n%.2f for %s,\n", latestPtr->debit, latestPtr->description);
showMenu();
}
else
{
printf("\nAll DirectDebits have been removed.\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
}
break;
}
case 2:
{
if(!isEmpty())
allList();
else
{
printf("\nYou have no DirectDebits\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
}
break;
}
case 3:
{
printf("\nWhat is the amont of new DirectDebit?\n");
scanf("\n%f", &deb);
printf("\nPlease give a brief, unique description of the new DirectDebit\n");
fgets(info, 100, stdin);
scanf("%[^\n]%*c", info);
printf("\n Your DirectDebit amount is : %.2f", deb);
printf("\n And the description is: %s", info);
add(deb, info);
printf("\n");
showMenu();
break;
}
case 4:
{
if(!isEmpty())
{
if(latestPtr->next != NULL)
{
printf("\nPlease enter the number of the DirectDebit you wish to remove, by counting from the bottom up:\n");
allList();
scanf("\n%d", &n);
printf("\nRemoving DirectDebit\n");
printf("\n%.2f is removed from the list",rmv(n));
}
else
{
printf("\nAll DirectDebits have now been removed.\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
latestPtr = NULL;
}
}
else
{
printf("\nYou have no DirectDebits\n");
printf("To see the menu, select option 5,\n");
printf("Or to quit, select option 6.\n");
}
break;
}
case 5:
{
showMenu();
break;
}
case 6:
printf("Thank you, Goodbye!\n");
exit(1);
break;
default:
printf("\nInvalid choice.\n");
showMenu();
break;
}
}
}
int isEmpty(void)
{
if(latestPtr == NULL)
return true;
else
return false;
}
void allList()
{
struct Banknode *scanPtr = NULL;
scanPtr = latestPtr;
printf("\nYour current DirectDebits are: \n");
while(scanPtr->next != NULL)
{
printf("%.2f for %s,\n",scanPtr->debit, scanPtr->description);
scanPtr = scanPtr->next;
}
printf("%.2f for %s,\n",scanPtr->debit, scanPtr->description);
}
void add(float fig, char info[100])
{
struct Banknode *newPtr = (struct Banknode*)malloc(sizeof(struct Banknode));
if (newPtr != NULL)
{
newPtr->debit = fig;
strcpy((newPtr->description), info);
newPtr->next = latestPtr;
latestPtr = newPtr;
}
else
{
printf("%.2f not inserted. No memory available.\n", fig);
}
free(newPtr);
}
float rmv(int n)
{
int len = 0, i;
struct Banknode *rmvPtr = latestPtr;
while (rmvPtr != NULL)
{
rmvPtr = rmvPtr->next;
len++;
}
if (len < n)
return -9999;
else
rmvPtr = latestPtr;
for (i = 1; i < len-n+1; i++)
rmvPtr = rmvPtr->next;
float j = latestPtr->debit;
latestPtr = latestPtr->next;
return j;
}
void showMenu()
{
printf("\nPlease select an option:");
printf("\n1. View Latest DirectDebit");
printf("\n2. View all DirectDebits");
printf("\n3. Add a DirectDebit");
printf("\n4. Remove a DirectDebit");
printf("\n5. Show menu");
printf("\n6. Exit\n");
}

I can't display binary content

I'm trying to write a simple phone book program. I have completed the first function and according to I observe it works without error. However, in second function (which is ""display()"") I can't show to user after I enter person knowledge. I'm working with binary mode. What the problem is in second function I couldn't understand. If you examine and help I'll be satisfied. Thanks in advance.
#include <stdio.h>
#include <stdlib.h> // "stdlib" library contains of exit() function
#include <malloc.h> // "malloc" library contains of malloc() function
#include <Windows.h> // "Windows" library contains of Sleep() function which waits the system as you want
#include <io.h> // "io" library contains of filelength() function
struct personKnowledge
{
char name[32];
char surname[32];
char number[32];
};
FILE *ptrFILE,*ptrFILE1;
long int recordLength,totalRecordLength,location;
static int counter = 0;
int number,totalRecordNumber;
void newRecord();
void display();
void deletE();
void add();
void update();
int main()
{
int choice;
do
{
printf("\n\t\t --- Phone Book Program ---");
printf("\n\n\t\t 1) New record"); // The options are being presented to user
printf("\n\n\t\t 2) Display person knowledge");
printf("\n\n\t\t 3) Delete someone");
printf("\n\n\t\t 5) Update person knowledge");
printf("\n\n\t\t 6) Exit");
printf("\n\n\nEnter your choice: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
newRecord();
break;
}
case 2:
{
display();
break;
}
case 3:
{
break;
}
case 4:
{
break;
}
case 5:
{
break;
}
case 6:
{
printf("\nWorking has been completed.\n");
return 0;
}
default:
{
printf("\nWrong entry! The program has been terminated.\n");
break;
}
}
} while (choice >= 1 && choice <= 6);
return 0;
}
void newRecord()
{
if ((ptrFILE = fopen("Phone Book.dat", "wb")) == NULL)
{
printf("The file couldn't open\n");
exit(0);
}
system("cls"); // Screen is being cleaned
struct personKnowledge *p; // p means person
p = (struct personKnowledge *)malloc(sizeof(struct personKnowledge)); // Memory is being allocated
fflush(stdin);
recordLength = sizeof(p); // size of p
printf("|| For the %d. person ||\n", counter+1);
printf("\n\Express person name: "); // User is entering the person's knowledge and they are being saved in file
gets(p->name);
printf("Express %s's surname: ", p->name);
gets(p->surname);
printf("Express %s's number: ", p->name);
gets(p->number);
fwrite(&(*p), recordLength, 1, ptrFILE);
printf("\nPlease wait, information is saving to file..\n");
Sleep(750);
printf("*-* Saving operation has been completed succesfully. *-*\n");
free(p);
counter++;
fclose(ptrFILE);
}
void display()
{
if ((ptrFILE = fopen("Phone Book.dat", "rb")) == NULL)
{
printf("The file couldn't open\n");
exit(0);
}
system("cls"); // Screen is being cleaned
struct personKnowledge *s; // s means searching
s = (struct personKnowledge *)malloc(sizeof(struct personKnowledge));
fflush(stdin);
recordLength = sizeof(s);
totalRecordLength = filelength(fileno(ptrFILE));
totalRecordNumber = totalRecordLength / recordLength;
printf("\n\nExpress person record number which you search: ");
scanf("%d", &number);
location = (number - 1)*recordLength;
fseek(ptrFILE, location, SEEK_SET);
fread(&(*s), recordLength, 1, ptrFILE);
printf("\n*-* Person knowledge which you search *-*\n");
Sleep(750);
printf("Name: %s\n", s->name);
printf("Surname: %s\n", s->surname);
printf("Number: %s\n", s->number);
free(s);
fclose(ptrFILE);
}
recordLength = sizeof(p);
is wrong, this is the size of the pointer which is normally 4 on a 32 bit system and 8 on a 64 bit syste.
you need
recordLength = sizeof(*p);
or
sizeof(struct personKnowledge);
which gives you the size of the structure pointed by p.

How can I read data from file?

I'm trying to create phone book which has five function in c. I have formed just first function which takes and saves in file people's knowledge. However, I cannot succeed the second function which search just a person's (Not all people) knowledge from file.
To run this function (""display() function"") I want to a name from user to search and to display that name's knowledge on the screen. I wrote something but it didn't work. The problem is display() function. How can I read just one line and print it on the screen? Thanks in advance.
#include <stdio.h>
#include <stdlib.h> // "stdlib" library contains of exit() and malloc function
#include <Windows.h> // "Windows" library contains of Sleep() function
#include <string.h> // "string" library contains of strcmp() function
struct personKnowledge
{
char number[16];
char name[16];
char surname[16];
};
void newRecord();
void display();
void deletE();
void add();
void update();
FILE *ptrFILE;
int main()
{
int choice;
printf("\n\t\t *-* Phone Book Program *-*");
do
{
printf("\n\n\t\t 1) New record"); // The options are being presented to user
printf("\n\n\t\t 2) Display person knowledge");
printf("\n\n\t\t 3) Delete someone");
printf("\n\n\t\t 4) Add new person");
printf("\n\n\t\t 5) Update person knowledge");
printf("\n\n\t\t 6) Exit");
printf("\n\n\nEnter your choice: ");
scanf("%d", &choice);
switch (choice)
{
case 1:
{
newRecord();
break;
}
case 2:
{
display();
break;
}
case 3:
{
break;
}
case 4:
{
break;
}
case 5:
{
break;
}
case 6:
{
printf("\nWorking has been completed.\n");
exit(0);
break;
}
default:
{
printf("\nWrong entry! The program has been terminated.\n");
}
}
} while (choice >=1 && choice <=6 );
return 0;
}
void newRecord()
{
system("cls"); // Screen is being cleaned
if ((ptrFILE = fopen("Phone Book.txt", "w")) == NULL)
{
printf("The file couldn't open\n");
}
else
{
struct personKnowledge *p; // p means person
p = (struct personKnowledge *)malloc(sizeof(struct personKnowledge)); // Memory is being allocated
fflush(stdin);
printf("\n\nDetermine person name: "); // User is entering the person's knowledge and they are being saved in file
gets(p->name);
printf("Determine %s's surname: ", p->name);
gets(p->surname);
printf("Determine %s's number: ", p->name);
gets(p->number);
fprintf(ptrFILE, "Name\t\t\t\tSurname\t\t\t\t\tNumber\n");
fprintf(ptrFILE, "--------\t\t ----------------\t\t\t---------------------\n");
fprintf(ptrFILE, "\n%s%33s%38s\n", p->name, p->surname, p->number);
fclose(ptrFILE);
free(p);
printf("Please wait, information is saving to file..\n");
Sleep(1000);
printf("*-* Saving operation has been completed. *-*");
}
fclose(ptrFILE);
}
void display()
{
struct personKnowledge *s; // s means searching
char name[16];
if ((ptrFILE = fopen("Phone Book.txt", "r")) == NULL)
{
printf("The file couldn't open\n");
}
else
{
fseek(ptrFILE, 0L, SEEK_SET);
printf("Express name which you search: ");
gets(s->name);
while (!feof == NULL)
{
fscanf(ptrFILE,"%s", &name);
if (strcmp(s->name, name) == 0)
{
printf("qawsdsdf");
}
}
}
fclose(ptrFILE);
}
In answer to one of your questions, I recommend rewriting this loop in display()
while (!feof == NULL) // wrong way to use feof
{
fscanf(ptrFILE,"%s", &name); // might overflow the string space
if (s->name == name) // wrong way to compare strings
{
printf("qawsdsdf"); // missing newline?
}
}
with this
while (fgets(name, sizeof(name), ptrFILE) != NULL) // safer way to read to a small buffer
{
name [ strcspn(name, "\r\n") ] = 0; // remove trailing newline etc
if (strcmp(s->name, name) == 0) // compare the strings
{
printf("qawsdsdf\n"); // added newline
}
}
EDIT in any case your posted code does not even compile properly:
while (!feof == NULL)
is rubbish, it should have been
while (!feof(ptrFILE))
although as I said is not the way to use feof anyway. This would not have happened if you had compiler warnings enabled and dealt with them.
I think these minor changes will solve your problem
Allocate memory for storing personKnowledge s = (struct personKnowledge *)malloc(sizeof(struct personKnowledge));
Make file pointer reach the starting location of data. A simple trick has been used to achieve this fscanf(ptrFILE, "Name\t\t\t\tSurname\t\t\t\t\tNumber\n");
fscanf(ptrFILE, "--------\t\t ----------------\t\t\t---------------------\n");
Make change in while loop.while (!feof(ptrFILE))
Scanning one row of data.fscanf(ptrFILE, "\n%s%33s%38s\n", s->name, s->surname, s->number)
Make change in string comparison.if (strcmp(name,s->name) == 0)
The modified display function
void display(){
struct personKnowledge *s;
s = (struct personKnowledge *)malloc(sizeof(struct personKnowledge)); // Memory is being allocated for s
fflush(stdin);
char name[16];
if ((ptrFILE = fopen("Phone Book.txt", "r")) == NULL)
{
printf("The file couldn't open\n");
}
else
{
fseek(ptrFILE, 0L, SEEK_SET);
printf("Express name which you search: ");
scanf("%s",name); //the name you want to retrieve
fscanf(ptrFILE, "Name\t\t\t\tSurname\t\t\t\t\tNumber\n");
fscanf(ptrFILE, "--------\t\t ----------------\t\t\t---------------------\n"); //when we read the file for first time we need to start from the first location of person data, this is a trick to make ptrFILE reach there
fflush(stdin);
while (!feof(ptrFILE))
{
fscanf(ptrFILE, "\n%s%33s%38s\n", s->name, s->surname, s->number);//same format as fprintf used in newRecord
if (strcmp(name,s->name) == 0) //comparison
{
printf("qawsdsdf");
}
}}fclose(ptrFILE);}
My solution was to change how the file is formatted
fprintf(ptrFILE, "\n%s%33s%38s", p->name, p->surname, p->number);
Because if you're using a program to retrieve information, there's no need to fill it with a bunch of junk headers every time you write to it.
I then edited the display function to be able to retrieve said information.
void display()
{
struct personKnowledge s; // s means searching
char name[16];
char sname[16];
char number[16];
char surname[16];
if ((ptrFILE = fopen("Phone Book.txt", "r")) == NULL)
{
printf("The file couldn't open\n");
}
else
{
printf("Express name which you search: ");
scanf("%s", &sname);
do
{
fscanf(ptrFILE,"%s%33s%38s", &name, &surname, &number);
if (strcmp(sname, name) == 0)
{
printf("%s %s %s", name, surname, number);
}
}
while (strcmp(sname, name) != 0);
}
}
P.S. I'm still new to c myself and I don't think I could give you a good explanation as to why my code works and yours doesn't. But I can say that those headers you were writing to the file every time was a major part of the problem when I was troubleshooting your code.

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