Delete Record in a File (C Programming) - c

I'm fairly new to C. At the moment, I'm learning about file management.
To further my understanding of files I wanted to create a Employee Database System, where the user can Create, Delete, Update or Retrieve an Employee Record. First I created a struct which contains the employee's variables like ID, first name, last name and pay, then a function which creates the records, but the there is the problem. I know how to search from the file (using the ID number) but I don't know how to delete a particular record.
(I'm so sorry because I accidentally deleted my DeleteFunction so I cannot show that particular function in my code)
My code does run well as far as I know, but you will find any errors
So here is my code:
#include <stdio.h>
#include <string.h>
typedef struct employee{
int id;
char name[40];
float pay;
}EMP;
void CreateEmployee(struct employee [] );
void DisplayRecord();
int main() {
EMP e[20];
CreateEmployee(e);
//return 0;
DisplayRecord();
return 0;
}
void CreateEmployee(struct employee x[]){
char choice ='y';
int i=0;
//EMP employee[20];
FILE *fp;
fp = fopen("employee.txt","a");
if (fp==NULL){
printf("File not created");
}
while((choice == 'Y') || (choice =='y')){
printf("Enter the employee's id:");
scanf("%i",&x[i].id);
fprintf(fp,"%i\t",x[i].id);
printf("\nEnter the employee's name:");
scanf("%s",x[i].name);
fprintf(fp,"%s\t",x[i].name);
printf("\nEnter the employee's pay:");
scanf("%f",&x[i].pay);
fprintf(fp,"%.2f\t\n",x[i].pay);
printf("\nEnter another employee?\n");
printf("Y - Yes N - No:\n");
scanf("\n%c",&choice);
i++;
}
fclose(fp);
}
void DisplayRecord(){
EMP temp;
FILE *fp = fopen("employee.txt", "r");
if(fp != NULL)
{
while( !feof(fp) )
{
fscanf(fp, "%i %s %f", &temp.id, temp.name, &temp.pay);
printf("%i %s %f\n",temp.id, temp.name, temp.pay);
}
fclose(fp);
}
else
{
printf("An error occurred opening the file\n");
}
}
I don't know how to use random access file as yet; that's why I'm using sequential access at the moment.

To delete a record, you have several choices:
Prepare by having a deleted field in each record, and when reading records, skip those that have deleted == true. To actually delete a record, set its deleted flag to true and save it.
Read the data file and write all records to a temporary file, except the one you want to delete. Finally, rename the temporary file to employees.txt.
Switch to a real database for managing the records, since all the typical operations are fast and easy then.
By the way, you haven't said why you love C as a programming language. If it is because you can quickly get your things done, you will be disappointed as soon as your programs get a little larger, since you have to do the memory management and error handling explicitly in your code. And, C makes it very easy to shoot you in the foot (so your program crashes and just doesn't work), since it doesn't have built-in memory protection. Therefore, before totally falling in love with that language, look around a little bit too see whether you can find something better.

Related

How can i find the data i need in a record?

I'm writing a project in c. Everything seems to work just fine but one function. This function allows the user of the program to edit a registered record by searching its ID(which is an integer part of a struct as in struct generalPatient{...int id;...}): so, the user inserts the Id and if there's a correspondence in the read file the user can start inserting the new data.
Here's the important part of the code i've written:
FILE *writePatient = fopen("data.dat", "rb+");
if (writePatient == NULL) {
fprintf(stderr, "\nError opening file\n");
exit(1);
}
else {
puts("Insert account Id you need to edit.");
int editId;
scanf("%d", &editId);
int fnd = 0;
int elsw, chsz = sizeof(struct generalPatient);
while (fread(&patient, chsz, 1, writePatient))
{
if (editId == patient.id){
do stuff
}
The rest of the code is not important because the "if" won't verify the condition and no matter how many IDs i try, it never finds a correspondence. So, the error must be in these lines. Can anybody find the problems in these few lines of codes or at least suggest me where could the problem be? I've written an identical function to allow user to edit data of another struct and it works. I really have no idea how to fix this.
EDIT:
I write on the patient file using "a" mode, so that it should always add a new record on the end of the file. The id is inserted automatically like this:
srand(time(NULL));
patient.id=1 + rand()%9999;
and the writing is done like this, after letting he user insert all the required data:
fwrite (&patient, sizeof(struct generalPatient), 1, writePatient);
To add further information, I've written a function that lets the user search for a specific patient using the patient's id and it works fine:
readPatientPointer = fopen ("data.dat", "r");//apertura file
if (readPatientPointer == NULL){
fprintf(stderr, "\nError opening file\n");
exit (1);
}else{
int check=0;
puts("Insert ID of the patient you're looking for.\nInsert a char to exit the program.");
int searchId;
if(scanf("%d", &searchId)!=1){
puts("bye.");
return EXIT_SUCCESS;
}
while(fread(&patientRead, sizeof(struct generalPatient), 1, readPatientPointer)){
if(searchId==patientRead.id){
do stuff}
Ok i figured it out. I simply had to change rb+ in r+. That is super weird because other functions that were written and linked with other functions in the same identical way were working but oh well, black magic.

why is my search function for file handling(.txt file) not working?

I want to search the structure (and print other details of book) I have added for the book for a particular issueNumber entered by user in the .txt file.
When I run the code it terminates after asking for user input (issueNumber-issuenumber).
I don't understand the issue behind this, I think there there is some issue with the while loop (code inside it).
Also I am not finding any good resource on file handling on the internet (maybe only for text mode). It would be helpful if someone suggest good resource.
Below is my code for searching for issueNumber and printing other details too.
My structure:
struct data
{
char author[25];
int issueNumber;
char title[25];
int issued;
};
My search function:
void searchBookByIssueNumber(FILE *fp)
{
struct data data2;
data2.issued = 0;
int issuenumber = 0;
printf("enter issue no.");
scanf("%d", &issuenumber);
while (fscanf(fp, "%s %d %s %d\n", data2.author, &data2.issueNumber, data2.title, &data2.issued) != EOF)
{
if (data2.issueNumber == issuenumber)
{
fseek(fp, -5, SEEK_CUR);
printf("%s %d %s", data2.author, data2.issueNumber, data2.title);
}
}
fclose(fp);
}
Start function:
void start(FILE *fp)
{
printf("---------------------------------------------------\n");
printf("| |\n");
printf("| WELCOME TO LIBRARY MANAGEMENT |\n");
printf("| |\n");
printf("---------------------------------------------------\n");
/*login();*/
/*addBook(fp);*/
searchBookByIssueNumber(fp);
}
Main function:
int main()
{
FILE *fp;
fp = fopen("c1.txt", "w+");
start(fp);
return 0;
}
Here is a working version of your code (I didn't fix gets but it's definitely something you shoud do, more info in 3. and I removed all the unused functions for the sample)
The corrected issues are:
1.
while (fscanf(fp, "%s %d %s %d\n", data2.author,
&data2.issueNumber, data2.title, &data2.issued) != EOF) {/*...*/}
When you read ints you need to pass to scanf the address of the variable where you want to store the value. data2.issueNumber needs to be &data2.issueNumber, data2.issued needs to be &data2.issued.
I used != EOF condition and it produced an infinite loop in my compiler(check it here), though this may not always happen, using == 4 condition is, IMO, a better way to do it.
"%s is not a safe specifier, it's vulnerable to buffer overflow, use "%24s" for a 25 char container.
In all it should be:
while (fscanf(fp, "%24s %d %24s %d\n", data2.author,
&data2.issueNumber, data2.title, &data2.issued) == 4) {/*...*/}
2. The file is being whiped when you open it, I used "r" or "r+" flag.
3. (This one is not corrected, the link has info on how to replace it)
gets() is a deprecated function, though some compilers still have it, this is an extremely vulnerable function and you should not use it.

Moving data from one program to another program using file structures c

Program(A)-----> file.txt-----> Program(B)
^This is the format I am using, I currently don't have enough knowledge with file structures.
My text file is named myStudents.txt
EDIT: Program(A) writes the information properly. Program(B) needs to retrieve the information from the text file.
#include<stdio.h>
int main()
{
char studentName[50];
int grade=0;
printf("Which students grade would you like to retrieve?: ");
scanf("%s",&studentName);
FILE *fptr;
fptr = (fopen("myStudents.txt", "r"));
if(fptr == NULL)
{
printf("Error!");
exit(1);
}
printf("\nStudent details:\n");
fscanf(fptr,"%d %[^\n]s",grade,studentName);
printf("Name: %s\n",studentName);
printf("Grade: %d\n",grade);
fclose(fptr);
return 0;
}
I'm very confused on how to use program A's information in program B. Apologies if this is a repeat thread, I couldn't find any information here or anywhere else to solve my issue.
*Note(A solid explanation would be very helpful along with any constructive criticism)
Cheers! Have a good day!
Your program B does actually not search for any name, it just tries to print the first one. I won't write the complete code for you but here is a little help with what your program should do:
read in the file line by line. (functions fscanf, fgets or getline may be useful)
extract the name and grade out of the line. (sscanf and all string functions)
check if the name is the one you are looking for, if yes print it and stop.
This is of course only an example what the program could look like, but i suggest to start by implementing this steps.

Modifying values of existing text file (C Programming Language)

Let's say I have a file name already created named "room.txt" and it contains the following:
20 10 5
Once I execute the code below, I will be asked to specify which variable to decrease its value by 1.For example: If I input "1" it will reduce the number "20" in "room.txt".However, it doesn't reduce the value.Instead, it deletes the contents of "room.txt" file.How do I make it so that it retains the values in the file when I enter my input from the program?Also, how do I reduce the values '20' '10' '5' respectively when I input '1' '2' '3' in my program?
#include<stdio.h>
char rooms[]={"rooms.txt"};
struct rooms {
int stdsuite;
int premsuite;
int deluxesuite;
};
int stdsuite;
int premsuite;
int deluxesuite;
void availablerooms ()
{
FILE*fp;
fp = fopen(rooms,"r");
fscanf(fp,"%d %d %d",&stdsuite,&premsuite,&deluxesuite);
system("cls");
system("cls");
printf("\n\n");
printf("\t\t-----------------------------------------------\n");
printf("\t\t Room Availability\n");
printf("\t\t-----------------------------------------------\n\n");
printf("--------------------------------------------------------------------------------\n\n");
printf("\t\t Standard Suite :\t%d / 20\n\n",stdsuite);
printf("\t\t Premium Suite :\t%d / 10\n\n",premsuite);
printf("\t\t Deluxe Suite :\t%d / 5\n\n",deluxesuite);
printf("--------------------------------------------------------------------------------\n\n");
fflush(stdin);
}
int main ()
{
int choice;
FILE*fp;
availablerooms();
printf("1. Standard Suite\n\n2. Premium Suite\n\n3. Deluxe Suite\n\n");
printf("Please enter the selected room value (1-3): ");
scanf("%d",&choice);
fflush(stdin);
if (choice == 1)
{
fp = fopen(rooms,"w");
stdsuite--;
}
else if (choice == 2)
{
fp = fopen(rooms,"w");
premsuite--;
}
else if (choice == 3)
{
fp = fopen(rooms,"w");
deluxesuite--;
}
else
printf("\nThe input is invalid!");
}
Any help would be greatly appreciated! :)
To accomplish what you're trying to do in standard C you must:
Open the file for reading "r".
Read its contents to your own datastructure.
Modify the data structure.
freopen the file for writing "w".†
Write back the modified data structure.
Close the file.
† This is necessary because there is no standard C way to truncate the file in "r+" mode.
availablerooms should fclose(fp) before returning. And fflush(stdout) instead of stdin.
Then, when trying to write the data back, you only fopen the file, but you don't write anything to it. There you have a major misconception of how the things work. in the 3 ifs, you decrement the relevant variables. But that are purely in-memory operations. opening the file before, doesn't change that. So, remove the three fopens and put a new one after the last if statement followed by a fprintf(fp, "%d %d %d", stdsuite, premsuite, deluxesuite); to do the actual writing. then finish with an fclose(fp) again

C - Price look-up program

I was asked to make a C program that act as a 'price lookup' where a user enter a product name and the program will print it's name and price which is stored in a file. If the item is not present in the file, the program will let the user know. The program will keep looping as long as the user wants to search. I did the coding using Dev C++, however after i run the code, the program got stuck after a few loops, and it's random. Could you guys detect any problem with my coding, or is it just the problem with Dev C++? I include my code below. Your help is greatly appreciated.
#include<stdio.h>
#include<stdlib.h>
#include<string.h>
#include<conio.h>
#include<ctype.h>
int main()
{
FILE *items;
char *mode="r";
char pName[50];
float pPrice;
char p1Name[50];
int value=0;
char respond='Y';
char s[50];
items=fopen("Product_Name_Price.txt", mode);
if(items==NULL)
{
fprintf(stderr, "Can't open file Product_Name_Price.txt!\n");
exit(1);
}
printf("File has been successfully opened\n");
do
{
printf("Enter the name of the product you wish to look for\n");
scanf("%s", &p1Name);
while(strcmp(p1Name, pName) !=0)
{
fscanf(items,"%s %f", pName, &pPrice);
//printf("%s\t%.2f\n", pName, pPrice);
//value=strcmp(p1Name, pName);
if(strcmp(p1Name, pName) == 0)
{
printf("%s\t%.2f\n", pName, pPrice);
}
}
/*
else
{
printf("No data in system\n");
}
*/
printf("Do you wish to look up for more item? (Y/N)\n");
scanf("%s", &respond);
}while(respond=='Y'|| respond=='y');
printf("This program is closing\n");
fclose(items);
}
Your program has undefined behaviour because your scanf("%s", &response) reads into response as if it were an array of sufficient size for the string being read — that size is at least 2 (including null terminator), but response is just one character. You blew up your stack and corrupted memory and then all bets are off.
You could write scanf("%c", &response) instead to actually read a single character, though you'd be better off switching to modern, safer tools if you're writing a C++ program.

Resources