Name and lastname search functions won't work. Why? [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 8 years ago.
Improve this question
I made a function as my project and name search/lastname search functions are not working and giving a runtime error. I can't really see the mistake. So what's wrong it?
Also ID and Mark search system has some bugs with them, whenever you search for an ID it also brings mark = 0, also if you search for Mark, it will bring ID = 0.
Full code:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
struct Student
{
long long int id;
char firstname[20];
char lastname[20];
int mark;
} student;
void
storeRecord()
{
FILE *fp;
printf("\nEnter Student Details:\n\nID number: ");
scanf_s("%lld",&student.id);
printf("\nName:");
scanf_s("%19s",student.firstname);
printf("\nSurname:");
scanf_s("%19s",student.lastname);
printf("\nMark(0 - 100 integer) : ");
scanf_s("%d",&student.mark);
fp = fopen("studentfile.txt","a+"); /* check if the file was opened */
if (fp == NULL)
return;
fprintf(fp, "\n%lld\t%s\t%s\t%d\t",
student.id,
student.firstname,
student.lastname,
student.mark);
fclose(fp);
printf("A student record has been added successfully...\n");
getchar();
}
int
compareStudentsById(struct Student lhs, struct Student rhs)
{
return (lhs.id == rhs.id);
}
int
compareStudentsByName(struct Student lhs, struct Student rhs)
{
return (strcmp(lhs.firstname, rhs.firstname) == 0);
}
int
compareStudentsByLastame(struct Student lhs, struct Student rhs)
{
return (strcmp(lhs.lastname, rhs.lastname) == 0);
}
int
compareStudentsByMark(struct Student lhs, struct Student rhs)
{
return (lhs.mark == rhs.mark);
}
void
printStudent()
{
printf("\nThe record is found.\n");
printf("\nID: %lld\nName: %s\nSurname: %s\nMark: %d \n",
student.id,
student.firstname,
student.lastname,
student.mark
);
}
void
searchStudent(int(*compare)(struct Student,struct Student), const char *const name, const char *const lastname, long long int id, int mark)
{
FILE *fp;
int found;
int matches;
if (name != NULL)
printf("Searching record with Name = %s.\n", name);
if (lastname != NULL)
printf("Searching record with Surname = %s.\n", lastname);
if (id != -1)
printf("Searching record with ID = %lld.\n", id);
if (mark != -1)
printf("Searching record with Mark = %d.\n", mark);
found = 0;
fp = fopen("studentfile.txt", "r");
if (fp == NULL)
{
printf("IO error\n");
return;
}
do
{
struct Student other;
if (name != NULL)
strcpy(other.firstname, name);
if (lastname != NULL)
strcpy(other.lastname, lastname);
other.id = id;
other.mark = mark;
matches = fscanf(fp,"\n%lld\t%s\t%s\t%d\t",
&student.id,
student.firstname,
student.lastname,
&student.mark);
if (matches == 4)
found = (compare(student, other) != 0);
} while ((matches == 4) && (found == 0));
if (found != 0)
printStudent();
else
printf("Not found...\n");
getchar();
}
void
searchStudentByName()
{
char studentname[20];
printf("\nEnter student first name: ");
scanf_s("%19s", studentname);
searchStudent(compareStudentsByName, studentname, NULL, NULL, NULL);
}
void
searchStudentById()
{
long long int id;
printf("\nEnter ID: ");
scanf_s("%lld", &id);
searchStudent(compareStudentsById, NULL, NULL, id, NULL);
}
void
searchStudentByLastname()
{
char studentlastname[20];
printf("\nEnter student surname: ");
scanf_s("%19s", &studentlastname);
searchStudent(compareStudentsByLastame, NULL, studentlastname, NULL, -1);
}
searchStudentByMark()
{
int mark;
printf("\nEnter Mark: ");
scanf_s("%d", &mark);
searchStudent(compareStudentsByMark, NULL, NULL, NULL, mark);
}
int main()
{
int choice;
choice = 0;
while (choice != 5)
{
printf("\n\tC PROGRAM OF STUDENT DATABASE SYSTEM");
printf("\n1 -> Store a new record in database\n");
printf("2 -> Search a student record by Student First Name\n");
printf("3 -> Search a student record by ID\n");
printf("4 -> Search a student record by Surname\n");
printf("5 -> Search a student record by Mark\n");
printf("6 -> Quit Student Database");
printf("\n\n");
printf("Enter your choice : ");
scanf_s("%d",&choice);
switch(choice)
{
case 1:
storeRecord();
break;
case 2:
searchStudentByName();
break;
case 3:
searchStudentById();
break;
case 4:
searchStudentByLastname();
break;
case 5:
searchStudentByMark();
break;
}
}
getch();
return 0;
}

If you had compiled this code with warnings switched on (as everyone should do) and fixed the warnings, then this (amended) program would have mostly worked. Search by Mark works but ends the program. I'll leave that as something for you to fix.
void
printStudent()
{
printf("\nThe record is found.\n");
printf("\nID: %lld\nName: %s\nSurname: %s\nMark: %d \n",
student.id,
student.firstname,
student.lastname,
student.mark
);
}
void
searchStudent(int(*compare)(struct Student,struct Student), const char *const name, const char *const lastname, long long int id, int mark)
{
FILE *fp;
int found;
int matches;
if (name != 0)
printf("Searching record with Name = %s.\n", name);
if (lastname != 0)
printf("Searching record with Surname = %s.\n", lastname);
if (id != -1)
printf("Searching record with ID = %lld.\n", id);
if (mark != -1)
printf("Searching record with Mark = %d.\n", mark);
found = 0;
fp = fopen("studentfile.txt", "r");
if (fp == 0)
{
printf("IO error\n");
return;
}
do
{
struct Student other;
if (name != NULL)
strcpy(other.firstname, name);
if (lastname != NULL)
strcpy(other.lastname, lastname);
other.id = id;
other.mark = mark;
matches = fscanf(fp,"\n%lld\t%s\t%s\t%d\t",
&student.id,
student.firstname,
student.lastname,
&student.mark);
if (matches == 4)
found = (compare(student, other) != 0);
} while ((matches == 4) && (found == 0));
if (found != 0)
printStudent();
else
printf("Not found...\n");
getchar();
}
void
searchStudentByName()
{
char studentname[20];
printf("\nEnter student first name: ");
scanf("%19s", studentname);
searchStudent(compareStudentsByName, studentname, 0, 0, 0);
}
void
searchStudentById()
{
long long int id;
printf("\nEnter ID: ");
scanf("%lld", &id);
searchStudent(compareStudentsById, 0, 0, id, 0);
}
void
searchStudentByLastname()
{
char studentlastname[20];
printf("\nEnter student surname: ");
scanf("%19s", studentlastname);
searchStudent(compareStudentsByLastame, 0, studentlastname, 0, -1);
}
searchStudentByMark()
{
int mark;
printf("\nEnter Mark: ");
scanf("%d", &mark);
searchStudent(compareStudentsByMark, 0, 0, 0, mark);
}
int main()
{
int choice;
choice = 0;
while (choice != 5)
{
printf("\n\tC PROGRAM OF STUDENT DATABASE SYSTEM");
printf("\n1 -> Store a new record in database\n");
printf("2 -> Search a student record by Student First Name\n");
printf("3 -> Search a student record by ID\n");
printf("4 -> Search a student record by Surname\n");
printf("5 -> Search a student record by Mark\n");
printf("6 -> Quit Student Database");
printf("\n\n");
printf("Enter your choice : ");
scanf("%d",&choice);
switch(choice)
{
case 1:
storeRecord();
break;
case 2:
searchStudentByName();
break;
case 3:
searchStudentById();
break;
case 4:
searchStudentByLastname();
break;
case 5:
searchStudentByMark();
break;
case 6:
goto lend;
}
}
lend:;
return 0;
}
Hint: add a default clause with error message to the switch(choice) and change the if (choice != 5) to a better test.

Multiple usages of scanning a string like scanf_s("%19s", ...); are incorrect.
Do not use & before studentlastname.
Also pass the size of the buffer. This is the key difference between scanf() and scanf_s(): Sizes passed for char * arguments. A seg fault or other odd behavior may occur without the proper parameters.
Check the result of scanf_s()
char studentname[20];
// scanf_s("%19s", &studentlastname);
if (1 != scanf_s("%s", studentlastname, sizeof studentlastname)) {
Handle_Error();
}
IMO: Do not use scanf() nor scanf_s() for any user input. Instead use fgets() and sscanf() or sscanf_s(), etc.
char studentname[20];
char buffer[2 * sizeof studentname + 2]; // I like 2x buffers
if (fgets(buffer, sizeof buffer, stdin) == NULL) {
Handle_EOF();
}
if (1 != sscanf("%19s", studentlastname)) {
Handle_Error();
}
// or
if (1 != sscanf_s("%s", studentlastname, sizeof studentlastname)) {
Handle_Error();
}
Changing from scanf() to fgets() really works best if all user input is changed this way, including those getting numbers.
int main() --> int main(void) #Dirk Koopman
If the final getch() needed for your environment, if not consider deleting it.
BTW Good exit strategy with checking the result of matches = fscanf(fp,... and good code did not use feof().

Related

How to delete a record from FILE *fp in C?

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void Main_Menu();
void add_bookid();
void search_book();
void delete_book();
void mod_book();
void appExit();
void prompt();
typedef struct
{
int dd;
int mm;
int yy;
}DATE;
struct book
{
char author[10];
char ID[10];
DATE date;
char Btitle[10];
char Bpub[10];
};
struct book books;
int main()
{
Main_Menu();
return 0;
}
//Main Menu
void Main_Menu()
{
int choice;
while(1)
{
printf("\n=================================================");
printf("\n======= INVENTORY AND MONITORING OF BOOKS =======");
printf("\n=================================================");
printf("\n[1] Add Book ID\n");
printf("[2] Search Book\n");
printf("[3] Delete a Book\n");
printf("[4] Edit Book Info\n");
printf("[5] Exit\n");
printf("\n=================================================");
printf("\nEnter your choice: ");
scanf("%d",&choice);
printf("\n=================================================");
switch(choice)
{
case 1:
add_bookid();
break;
case 2:
search_book();
break;
case 3:
delete_book();
break;
case 4:
mod_book();
break;
case 5:
appExit();
break;
default:
printf("\n INVALID INPUT!");
prompt();
break;
}
}
}
void add_bookid()
{
int book [10];
int a;
printf("\n------------------ ADD BOOKS ------------------");
printf("\n----------You can add up to 10 books-----------");
printf("\n=================================================");
printf("\n How many books you will add?: ");
scanf("%d", &a);
int isFound = 0;
for(int i=0; i<a;i++)
{
FILE *fp;
fp = fopen("book.txt","ab+");
fflush(stdin);
printf("\n---------------------------------------");
printf("\n[%d]Add Book ID: ", i+1);scanf("%s",books.ID);
printf("\nAdd Book Title: ");scanf("%s",books.Btitle);
printf("\nAdd Author: ");scanf("%s",books.author);
printf("\nAdd Date of Publication: ");
printf("\nEnter Month (MM): ");scanf("%d", &books.date.mm);
printf("\nEnter Date (dd): ");scanf("%d", &books.date.dd);
printf("\nEnter Year(yyyy): ");scanf("%d", &books.date.yy);
printf("\nPublisher: ");scanf("%s",books.Bpub);
fwrite(&books, sizeof(books), 1, fp);
fclose(fp);
}
printf("\n-------------------------------------------------");
prompt();
}
void search_book()
{
system("cls");
printf("\n------------------ SEARCH BOOKS ------------------");
char b_id[10];
int isFound = 0;
printf("\nEnter Book ID to Search: ");fflush(stdin);
gets(b_id);
FILE *fp;
fp = fopen("book.txt","rb");
while(fread(&books,sizeof(books),1,fp) == 1)
{
if(strcmp(b_id,books.ID) == 0)
{
isFound = 1;
break;
}
}
if(isFound == 1)
{
printf("\nThe record is Found");
printf("\n---------------------------------------");
printf("\nBook Title:%s ", books.Btitle);
printf("\nAuthor:%s ", books.author);
printf("\nDate of Publication: %d - %d - %d ", books.date.mm,books.date.dd, books.date.yy);
printf("\nPublisher: %s ", &books.Bpub);
}
else
{
printf("Sorry, No record found\n");
printf("\n=========================================");
}
fclose(fp);
printf("\n-------------------------------------------------");
prompt(); // return to main menu
}
void delete_book()
{
system("cls");
printf("\n------------------ DELETE BOOKS ------------------");
char b_id[10];
int isFound = 0;
printf("\nEnter Book ID to Delete: ");fflush(stdin);
gets(b_id);
FILE *fp, *temp;
fp = fopen("book.txt","rb");
temp = fopen("temp.txt", "wb");
while(fread(&books, sizeof(books),1,fp) == 1){
if(strcmp(b_id, books.ID) == 0){
fwrite(&books,sizeof(books),1,temp);
}
}
fclose(fp);
fclose(temp);
remove("book.txt");
rename("temp.txt","book.txt");
printf("The record is successfully deleted");
printf("\n-------------------------------------------------");
prompt();
}
void mod_book()
{
system("cls");
printf("\n------------------ EDIT BOOK INFO ------------------");
char b_title[10];
int isFound = 0;
printf("\nEnter Book Title to edit: ");fflush(stdin);
gets(b_title);
FILE *fp;
fp = fopen("book.txt","rb+");
while(fread(&books, sizeof(books),1,fp) == 1){
if(strcmp(b_title, books.Btitle) == 0){
fflush(stdin);
printf("\nAdd New Book ID: ");scanf("%s",books.ID);
printf("\nNew Book Title: ");scanf("%s",books.Btitle);
printf("\nNew Author: ");scanf("%s",books.author);
printf("\nDate of Publication: ");
printf("\nEnter New Month (MM): ");scanf("%s", &books.date.mm);
printf("\nEnter New Date (dd): ");scanf("%s", &books.date.dd);
printf("\nEnter New Year(yyyy): ");scanf("%s", &books.date.yy);
printf("\nNew Publisher: ");scanf("%s",books.Bpub);
printf("\nInformation Successfully Edited ");
fseek(fp,-sizeof(books), SEEK_CUR);
fwrite(&books,sizeof(books), 1, fp);
isFound = 1;
break;
}
}
if(!isFound){
printf("No Record Found!");
}
fclose(fp);
printf("\n-------------------------------------------------");
prompt(); // return to main menu
}
void appExit()
{
printf("\n == Thank you for using the App! == \n");
}
void prompt()
{
printf("\nPress 1 if you want to go back to Main Menu, Press any key to Exit: ");
int ans;
scanf("%d",&ans);
if(ans == 1)
{
system("cls");
Main_Menu();
}
else
appExit();
}
Let's say that a user add a record,
book id: 1,
title: xyxy,
author: jho,
date of publication, 12 - 12 - 2012,
then the user select another function which is 3,
delete_book,
Enter Book ID to Delete: 1.
then it will print "The record is successfully deleted"
When the user select another function, search_book();
The output should be "Sorry, No record found"
But my code still prints the recorded data even if the user already delete it.
How to fix this?

The function sometime wont loop but will save the record, sometime it loop but didn't record

I am creating a module for club management system, but the function won't loop and save records. Sometimes it will loop but didn't save any record, sometimes won't loop but save the record. Can anyone fix my code?
#include<stdlib.h>
#include<stdio.h>
#include<string.h>
#include<ctype.h>
#include<conio.h>
#pragma warning(disable:4996)
// Structure of the employee
struct staff
{
char name[40];
int id[7];
int age[3];
char position[20];
};
struct staff s;
// size of the structure
long int recsize = sizeof(s);
FILE* fp, * ft;
void addrecord();
void deleterecord();
void displayrecord();
void modifyrecord();
void searchrecord();
void staffmenu();
char another;
//main menu
int menu()
{
int funsType;
fp = fopen("staff.dat", "rb+");
if (fp == NULL) {
fp = fopen("staff.dat", "wb+");
if (fp == NULL) {
printf("\nCannot open file...");
exit(1);
}
}
system("cls");
printf("1) Staff Information\n");
printf("2) Facility Information\n");
printf("3) Member Information\n");
printf("4) Booking Information\n");
printf("5) Facility Usage Information\n");
printf("Enter your requirement: ");
scanf("%d", &funsType);
switch (funsType) {
case 1: staffmenu(); break;
case 2: printf("2"); break;
case 3: printf("3"); break;
case 4: printf("4"); break;
case 5: printf("5"); break;
default: printf("Please choose the correct number");
getch();
menu();
}
return 0;
}
int main() {
menu();
staffmenu();
}
//show staff menu
void staffmenu() {
system("cls");
int choice;
printf("\n1. ADD RECORD\n");
printf("\n2. DELETE RECORD\n");
printf("\n3. DISPLAY RECORDS\n");
printf("\n4. MODIFY RECORD\n");
printf("\n5. SEARCH RECORD\n");
printf("\n6. EXIT\n");
printf("\nENTER YOUR CHOICE...\n");
fflush(stdin);
scanf("%d", &choice);
switch (choice) {
case 1:
addrecord();
break;
case 2:
deleterecord();
break;
case 3:
displayrecord();
break;
case 4:
modifyrecord();
break;
case 5:
searchrecord();
break;
case 6:
fclose(fp);
exit(0);
break;
default:
printf("\nINVALID CHOICE...\n");
getch();
staffmenu();
}
}
//add record to binary file
void addrecord()
{
system("cls");
another = 'y';
fseek(fp, 0, SEEK_END);
while (another == 'y') {
printf("\nEnter ID : ");
scanf("%s", &s.id);
printf("\nEnter Name : ");
scanf("%s", s.name);
printf("\nEnter Age : ");
scanf("%s", &s.age);
printf("\nEnter Position : ");
scanf("%s", s.position);
fwrite(&s, recsize, 1, fp);
printf("\nWant to add another record (Y/N) : ");
fflush(stdin);
scanf("%c", &another); //When I click n i will back to addrecord but the record didnt't save //It will loop but didn't save the record
another = getche();//read from keyboard
}
}
//delete record from binary file
void deleterecord()
{
system("cls");
char empname[50];
char another = 'y';
while (another == 'y') {
printf("Enter employee name to delete : ");
scanf("%s", empname);
ft = fopen("temp.dat", "wb");
rewind(fp);
while (fread(&s, recsize, 1, fp) == 1) {
if (strcmp(s.name, empname) != 0)
fwrite(&s, recsize, 1, ft);
}
fclose(fp);
fclose(ft);
remove("staff.dat");
rename("temp.dat", "staff.dat");
fp = fopen("staff.dat", "rb+");
printf("\nWant to delete another record (Y/N) :");
fflush(stdin);
another = getche(); // when I click n it will straight close the program but still no delete the record //It wont loop and save the record
}
}
//display all record from file
void displayrecord()
{
system("cls");
fp = fopen("staff.dat", "rb+");
if (fp == NULL) {
fp = fopen("staff.dat", "wb+");
if (fp == NULL) {
printf("\nCannot open file...");
exit(1);
}
}
rewind(fp);
printf("\n==========================================================");
printf("\nID\t\tNAME\t\tAGE\t\t\tPOSITION\n",s.id, s.name, s.age, s.position);
printf("==========================================================\n");
while (fread(&s, recsize, 1, fp) == 1)
printf("\n%s\t\t%s\t\t%s\t%s",s.id, s.name, s.age, s.position);
printf("\n\n\n\t");
printf("Press any key to back to menu......");
if (getch())
staffmenu();
}
//edit record from binary file
void modifyrecord()
{
system("cls");
char empname[50];
char another = 'y';
while (another == 'y') {
printf("\nEnter employee name to modify : ");
scanf("%s", empname);
rewind(fp);
while (fread(&s, recsize, 1, fp) == 1) {
if (strcmp(s.name, empname) == 0) {
printf("\nEnter new id:");
scanf("%s", &s.id);
printf("\nEnter new name :");
scanf("%s", s.name);
printf("\nEnter age :");
scanf("%s", &s.age);
printf("\nEnter new position :");
scanf("%s", &s.position);
fseek(fp, -recsize, SEEK_CUR);
fwrite(&s, recsize, 1, fp);
break;
}
}
// Ask for modifying another record
printf("\nWant to modify another"
" record (Y/N) :");
fflush(stdin);
another = getche();
}
}
//search record from binary file
// it can't continue search, it will trigger breakpoint
void searchrecord() {
system("cls");
int found = 0;
char namesearch[40];
char another = 'y';
while (another == 'y') {
printf("\n Enter Name to search : ");
scanf("%s", &namesearch);
if (fp == NULL) {
fp = fopen("staff.dat", "wb+");
if (fp == NULL) {
printf("\nCannot open file...");
exit(1);
}
}
rewind(fp);
while ((fread(&s, recsize, 1, fp) == 1))
{
if (strcmp(s.name, namesearch) == 0)
{
found = 1;
printf("\nRecord of Staff / Member of %s is\n", namesearch);
printf("===================================");
printf("\nID : %s", s.id);
printf("\nName : %s", s.name);
printf("\nAge : %s", s.age);
printf("\nPosition : %s", s.position);
}
}
if (found == 0)
printf("\nRecord Not Found\n");
fclose(fp);
printf("\nSearch another record(y/n) :");
fflush(stdin);
another = getche();
}
}
Hi i think the problem is that '\n' from the previous input is in the input stream. My solution would be not to read a char but a string.
// Structure of the employee
char another; -> char another[2];
//show staff menu
//void addrecord()
another = 'y'; -> sprintf(another, "y");
while (another == 'y') -> while (strcmp(another, "y") == 0)
scanf("%c", &another); another = getche(); -> scanf_s("%s", &another, (unsigned)sizeof(another));
these are only a few changes for void addrecord().
I think you would need to change everything with "another".

The following code doesn't store some information

While running this code I get an unwanted display: "the information for the salary is not displaying although I inputted the information" This problem most likely exist in line 131 in the insert section (). If I enter "900" for salary it displays "0.00." I also think it's related to the line of code just below it since the display of data changes back to normal however the data for the employee ID changes and prints the address. I ask if you know what's the issue if you could please intervene? Thank you in advance!!
struct here:
struct employee
{
char name[50];
char sex[7];
char adrs[50];
char dsgn[25];
int age;
int empID[9];
float slry;
};
Problem:
printf("\nEnter basic salary of the employee: ");
scanf("%f", &e.slry);
printf("\nEnter the employee's ID: ");
scanf("%8d", &e.empID[9]);
Entire code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <conio.h>
#include <ctype.h>
#include <stdbool.h>
#include <windows.h>
#include "struct.h"
void insert();
void list();
void edit();
void del();
void exit();
int tolower();
FILE * fptr, *ftemp;
struct employee e;
size_t recsize;
char empname[50];
int main()
{
int choice;
fptr = fopen("ems.txt", "r+");
if (fptr == NULL)
{
printf("Can't find file! Attempting to create file... \n");
fptr = fopen("ems.txt","w+");
if(fptr == NULL)
{
printf("Can't create file. Exiting...");
exit(1);
}
}
//Explain the reason for this?
recsize = (long int) sizeof(e);
while(1)
{
printf("*******************************\n");
printf("\nEmployee management system");
printf("\n1. Insert employee information");
printf("\n2. List all employee information");
printf("\n3. Edit employee information");
printf("\n4. Delete employee information");
printf("\n5. Exit");
printf("\n\n*****************************\n");
printf("\n\n Enter your choice: ");
scanf("%d", &choice);
int ch; while( ( ch = getchar() ) != EOF && ch != '\n' ){;}
switch(choice)
{
case 1:
puts("Insert was chosen");
insert();
break;
case 2:
puts("List was chosen");
list();
break;
case 3:
puts("Edit was chosen");
edit();
break;
case 4:
puts("Delete was chosen");
del();
break;
case 5:
puts("Exit was chosen");
exit(1);
break;
default:
puts("Choice is incorrect!!");
break;
}
}
return 0;
}
void insert()
{
char next;
do
{
printf("********************************************************** \n");
printf("\nEnter the name of the employee: ");
fgets(e.name, sizeof(e.name), stdin);
e.name[strcspn(e.name, "\n\r")] = '\0';
printf("\nEnter the sex of the employee (M/m or F/f): ");
scanf("%6s",e.sex);
switch(*e.sex)
{
case 'M':
case 'm':
break;
case 'F':
case 'f':
break;
default:
printf("Unspecified Sex.");
}
printf("\nEnter the address of the employee: ");
fseek(stdin, 0, SEEK_END); // ADD THIS TO AVOID SKIP
fgets(e.adrs, sizeof(e.adrs), stdin); // this
e.adrs[strcspn(e.adrs, "\n\r")] = '\0';
printf("\nEnter designation of the employee: ");
fgets(e.dsgn, sizeof(e.dsgn), stdin); // this
e.dsgn[strcspn(e.dsgn, "\n\r")] = '\0';
printf("\nEnter age of the employee: ");
scanf("%d", &e.age);
printf("\nEnter basic salary of the employee: ");
scanf("%f", &e.slry);
printf("\nEnter the employee's ID: ");
scanf("%8d", &e.empID[9]);
fwrite(&e,recsize,1,fptr);
int ch; while( ( ch = getchar() ) != EOF && ch != '\n' ){;}
printf("\nDo you want to input more? (y/n): ");
next = getche();
printf("\n");
}
while( tolower(next) != 'n' );
//fclose(fptr);
}
void list ()
{
/*printf("-------------------------------");
printf("\nEmployee Details: \n---------------------------------\n");
rewind(fptr);///moves file to start of the file
size_t fread(void *fptr, size_t size, size_t nmemb, FILE *stream)///read the file and fetch the record one record per fetch
{
printf("\n\n%s \t\t%6s \t%s \t%s \t%d \t%.2f \t%d",e.name, e.sex, e.adrs, e.dsgn, e.age, e.slry, e.empID[9]);
return 1;
}
getch();*/
printf("-------------------------------");
printf("\nEmployee Details: \n---------------------------------\n");
rewind(fptr);
/*size_t fread(void *fptr, size_t size, size_t nmemb, FILE *stream)///read the file and fetch the record one record per fetch
{*/
printf("Name : %s\n",e.name);
printf("Address : %s\n",e.adrs);
printf("Sex : %7s\n",e.sex);
printf("Designation : %s\n",e.dsgn);
printf("Age : %d\n",e.age);
printf("Salary : %.2f\n",e.slry);
printf("Employee-ID : %d\n",e.empID[9]);
/*return 1;
}*/
}
void edit ()
{
char next;
do
{
printf("Enter the employee's name to be edited: ");
scanf("%49[^\n]", empname);
rewind(fptr);
size_t fread(void *fptr, size_t size, size_t nmemb, FILE *stream)///fetch all records from file
{
if(strcmp(e.name,empname) == 0) ///if entered name matches with that in file
{
printf("\nEnter new name, sex, address, designation, age, salary and employee ID: ");
scanf("%s%c%s%s%d%f%d", e.name, e.sex, e.adrs, e.dsgn, &e.age, &e.slry, e.empID);
fseek(fptr, -recsize, SEEK_CUR);/// move cursor 1 step back from current position
fwrite(&e, recsize,1,fptr); ///override the record
}
return 1;}
printf("\nEdit another record(y/n)");
next = getche();
int ch; while( ( ch = getchar() ) != EOF && ch != '\n' ){;}
}
while(next != 'n');
return ;
}
void del()
{
char next;
do
{
printf("\nEnter name of employee to delete: ");
scanf("%s",empname);
ftemp = fopen("Temp.dat","wb"); ///create a intermediate file for temporary storage
rewind(fptr); ///move record to starting of file
size_t fread(void *fptr, size_t size, size_t nmemb, FILE *stream) ///read all records from file
{
if(strcmp(e.name,empname) != 0) ///if the entered record match
{
fwrite(&e,recsize,1,ftemp); ///move all records except the one which is to be deleted to temp file
}
return 1;
}
fclose(fptr);
fclose(ftemp);
remove("ems.txt"); ///remove original file
rename("Temp.dat","ems.txt"); ///rename temp file to original file name
fptr = fopen("ems.txt", "rb+");
printf("Delete another record(y/n)");
int ch; while( ( ch = getchar() ) != EOF && ch != '\n' ){;}
next = getche();
}while( tolower(next) != 'n' );
fclose(fptr);
exit(0);
}

Editing existing file in C

I am trying to make this simple hospital management system for my school project in C, when i try to edit the existing patient details by searching with their id number, That patient information gets edited, patient id,name etc but the problem is all other patients information that i don't want to edit becomes blank(means in place of id it becomes 0 and other remains blank except the edited patients details).
How do i edit only the details of patient i want to edit??
My code for editing
fp is my original filename and temp is temporary file i have created
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include<process.h>
typedef struct Hospital{
int patientId;
char fname[20];
char lname[20];
char gender[10];
int age;
char ReferredTo[30];
}Hospital;
Hospital hospi;
void Record();
void Display();
void Add();
void Edit();
void Search();
void Delete();
int main(){
int ch;
top:
printf("\n1.Create Record of patients");
printf("\n2.Display Record of patients");
printf("\n3.Append Record of Additional patients");
printf("\n4.Edit the record of the patients");
printf("\n5.Search record of the patients");
printf("\n6.Delete record of the patients");
printf("\n---------------------------------------");
printf("\nEnter your choice: ");
scanf("%d",&ch);
printf("\n---------------------------------------");
if(ch == 1){
Record();
}else if(ch == 2){
Display();
} else if(ch == 3){
Add();
//goto top;
}else if(ch == 4){
Edit();
}else if(ch == 5){
Search();
}else if(ch == 6){
Delete();
}else{
printf("Invalid Choice");
}
}
void Record(){
FILE *fp;
int n = 0,i;
fp = fopen("C:\\project\\record.txt","w");
if(fp == NULL){
printf("Couldn't Open the file");
}else{
printf("\nHow many Record You want to enter: ");
scanf("%d",&n);
for(i=0; i<n; i++){
printf("\nEnter Patient ID: ");
scanf("%d",&hospi.patientId);
printf("\nEnter Patient First Name: ");
scanf("%s",hospi.fname);
fflush(stdin);
printf("\nEnter Patient Last Name: ");
scanf("%s",hospi.lname);
printf("\nEnter Patient sex(M for male F for Female): ");
scanf("%s",hospi.gender);
printf("\nEnter Patient Age: ");
scanf("%d",&hospi.age);
printf("\nEnter the Doctor Name which the patients is refered to: ");
scanf("%s",hospi.ReferredTo);
fwrite(&hospi,sizeof(hospi),1,fp);
}
printf("\nData Successfully Recorded....:)");
}
fclose(fp);
}
void Display(){
FILE *fp;
fp = fopen("C:\\project\\record.txt","r");
if(fp == NULL){
printf("Error: can't open file");
}else{
while(fread(&hospi,sizeof(hospi),1,fp)==1){
printf("\nPatient Id = %d\n",hospi.patientId);
printf("Patient Fullname = %s %s\n",hospi.fname,hospi.lname);
fflush(stdin);
printf("Patient Gender: %s\n",hospi.gender);
printf("Patient Age = %d\n",hospi.age);
printf("Referred Doctorr = %s\n",hospi.ReferredTo);
printf("---------------------------------------\n");
}
}
fclose(fp);
}
void Add(){
FILE *fp;
char ch;
int n = 0,i;
fp = fopen("C:\\project\\record.txt","a");
if(fp == NULL){
printf("Error: can't open file");
}else{
//printf("\nHow many Additional patients you want to add: ");
//scanf("%d",&n);
printf("\nEnter Patient ID: ");
scanf("%d",&hospi.patientId);
printf("\nEnter Patient First Name: ");
scanf("%s",hospi.fname);
fflush(stdin);
printf("\nEnter Patient Last Name: ");
scanf("%s",hospi.lname);
printf("\nEnter Patient sex(M for male F for Female): ");
scanf("%s",hospi.gender);
printf("\nEnter Patient Age: ");
scanf("%d",&hospi.age);
printf("\nEnter the Doctor Name which the patients is refered to: ");
scanf("%s",hospi.ReferredTo);
fwrite(&hospi,sizeof(hospi),1,fp);
}
printf("\nDo you want to continue adding data press('y' for yes and 'N' for no ) ");
scanf("%s",ch);
while(ch =='y'){
Add();
}
fclose(fp);
}
void Edit(){
int Pid;
FILE *fp,*temp;
fp = fopen("C:\\project\\record.txt","r");
temp = fopen("C:\\project\\temp.txt","a");
Hospital hospt;
printf("\nEnter the patient ID you want to Edit the data: ");
scanf("%d",&Pid);
while(fread(&hospt,sizeof(hospt),1,fp)==1){
if(Pid == hospt.patientId){
printf("\nEnter Patient ID: ");
scanf("%d",&hospi.patientId);
printf("\nEnter Patient First Name: ");
scanf("%s",hospi.fname);
fflush(stdin);
printf("\nEnter Patient Last Name: ");
scanf("%s",hospi.lname);
printf("\nEnter Patient sex(M for male F for Female): ");
scanf("%s",hospi.gender);
printf("\nEnter Patient Age: ");
scanf("%d",&hospi.age);
printf("\nEnter the Doctor Name which the patients is refered to: ");
scanf("%s",hospi.ReferredTo);
fwrite(&hospi,sizeof(hospi),1,temp);
}else{
fwrite(&hospi,sizeof(hospi),1,temp);
}
}
fclose(fp);
fclose(temp);
remove("C:\\project\\record.txt");
rename("C:\\project\\temp.txt","C:\\project\\record.txt");
}
void Search(){
FILE *fp;
int found_name = 0;
char search_name[20];
printf("\nEnter the Patient name you want to search for: ");
scanf("%s",search_name);
fp = fopen("C:\\project\\record.txt","r");
while(fread(&hospi,sizeof(hospi),1,fp)==1){
if(strcmp(search_name,hospi.fname)==0){
found_name++;
printf("\nPatient Id = %d\n",hospi.patientId);
printf("Patient Fullname = %s %s\n",hospi.fname,hospi.lname);
fflush(stdin);
printf("Patient Gender: %s\n",hospi.gender);
printf("Patient Age = %d\n",hospi.age);
printf("Referred Doctorr = %s\n",hospi.ReferredTo);
break;
}
}
if(found_name==0){
printf("\nThe Patient Name you searched for is not register in our system...:(");
}
fclose(fp);
}
void Delete(){
FILE *fp,*temp;
Hospital hospt;
int delete_id,found = 0;
fp = fopen("C:\\project\\record.txt","r");
temp = fopen("C:\\project\\temp.txt","a");
printf("\nEnter the patient id you want to Delete: ");
scanf("%d",&delete_id);
while(fread(&hospt,sizeof(hospt),1,fp)==1){
if(delete_id != hospt.patientId){
fwrite((&hospt),sizeof(hospt),1,temp);
}else{
found++;
}
}
fclose(fp);
fclose(temp);
remove("C:\\project\\record.txt");
rename("C:\\project\\temp.txt","C:\\project\\record.txt");
if(found>0)
{
printf("Data found and delete successfully\n");
}else{
printf("The Patiend id you want to delete is not in the File");
}
}
You're writing hospi whether you update it or not; both if part and else part. You may want to write hospi when matching input, hospt otherwise.
while (fread(&hospt, sizeof(hospt), 1, fp) == 1) {
// ^^^^^
if (Pid == hospt.patientId) {
// ^^^^^
printf("\nEnter Patient ID: ");
scanf("%d", &hospi.patientId);
// ^^^^^
/* ... */
fwrite(&hospi, sizeof(hospi), 1, temp);
// ^^^^^
} else {
fwrite(&hospi, sizeof(hospi), 1, temp);
// ^^^^^
}
}

Reading struct from binary file (C)

I need your help with reading struct from binary file,
the "Grocery read_from_file ()..." function Can't get this to work!
Here is my code:
#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <ctype.h>
#include <conio.h>
struct grocerylist
{
int iD;
char grocery[30];
float amount;
char unit[10];
};
Grocery set_size_of(Grocery* list, int index);
Grocery input(int index);
void print_grocerylist(Grocery* list, int* index);
void write_to_file(FILE* file_pointer, Grocery* list, int index);
Grocery read_from_file(FILE* file_pointer, Grocery* list, int* index);
void change_item(Grocery* list, int index);
void remove_item(Grocery* list, int* index);
int main()
{
Grocery* list = (Grocery*)malloc(sizeof(Grocery)*1); //Grocery-array allocated memory for 1 struct
int index = 0, choice = 0;
FILE* file_pointer = NULL;
printf("Hey there user!\n");
while(choice != 7){
system("cls");
printf("Menu\n");
printf("1 - Add an item to the list.\n2 - Print the contents of your current list.\n3 - Print the contents to file.\n4 - Read from file.\n5 - Change an item on the list.\n6 - Remove item from the list.\n7 - close the program.\nChoose: ");
scanf("%d", &choice);
printf("\n");
switch(choice){
case 1:
list[index] = input(index);
index++;
*list = set_size_of(list, index); //Reallocating memory for the array of grocery-structs.
fflush(stdin);
break; //Add item
case 2:
print_grocerylist(list, &index); //Print list
fflush(stdin);
break;
case 3:
write_to_file(file_pointer, list, index); //print to file
fflush(stdin);
break;
case 4:
*list = read_from_file(file_pointer, list, &index); //read from file
fflush(stdin);
break;
case 5:
change_item(list, index); //change item
fflush(stdin);
break;
case 6:
remove_item(list, &index); //remove item
index--;
fflush(stdin);
break;
case 7:
free(list);
exit(EXIT_SUCCESS); //End program
break;
default:
printf("Wrong input, please try again!");
fflush(stdin);
getch();
break;
}
}
return 0;
}
Grocery set_size_of(Grocery* list, int index){ //reallocates memory.
list = realloc(list, (index+1)*sizeof(Grocery));
return *list;
}
Grocery input(index){
Grocery tmp;
int x = 0;
tmp.iD = index +1;
fflush(stdin);
printf("Grocery: ");
gets(tmp.grocery);
while(x == 0){
fflush(stdin);
printf("Amount: ");
x = scanf("%f", &tmp.amount);
if(x == 0){
puts("Error, please try again!");
}
}
fflush(stdin);
x = 0;
while(x == 0){
printf("Unit: ");
gets(tmp.unit);
if(isalpha(*tmp.unit)){
x = 1;
}else{
x = 0;
puts("Error: please try again!\n");
}
}
printf("\n");
return tmp;
}
void print_grocerylist(Grocery* list, int* index){
int i;
system("cls");
printf("The grocery list contains:\n");
printf("Item Amount Unit");
for(i=0;i<*index;i++)
{
printf("\n%d: %-10s %5.1f %6s", list[i].iD, list[i].grocery, list[i].amount, list[i].unit);
}
printf("\n");
getch();
printf("Press any key to continue.\n");
}
void write_to_file(FILE* file_pointer, Grocery* list, int index){ //works just fine afaik.. Prints the index at the start, fills it up with all the rest.
char filename[30];
memset(filename, '\0', sizeof(filename));
printf("What is the name of the file you wish to write to?: ");
scanf("%s", filename);
strcat(filename, ".txt");
file_pointer = fopen(filename, "wb");
if(file_pointer == NULL){
printf("Error!");
return;
}else{
fflush(stdin);
printf("File opened successfully!\n");
fwrite(&index, sizeof(int), 1, file_pointer);
fwrite(list, sizeof(Grocery), index, file_pointer);
printf("File written.");
getch();
}
fclose(file_pointer);
return;
}
Grocery read_from_file(FILE* file_pointer, Grocery* list, int* index){ //Can't get this to work...
char filename[30];
memset(filename, '\0', sizeof(filename));
printf("What is the name of the file you wish to read from?: ");
scanf("%s", filename);
strcat(filename, ".txt");
file_pointer = fopen(filename, "rb");
if(file_pointer == NULL){
printf("Error!");
return *list;
}else{
fflush(stdin);
free(list);
printf("File opened successfully!\n");
fread(index, sizeof(int), 1, file_pointer);
printf("Index %d read.\n", *index);
list = (Grocery*)calloc(*index, sizeof(Grocery));
fread(list, sizeof(Grocery), (*index), file_pointer);
printf("File read.");
getch();
fflush(stdin);
}
fclose(file_pointer);
return *list;
}
void change_item(Grocery* list, int index){ //Basically it's a more complex version of "Grocery input()" were we look to the ID/index and alter the information.
int x = 0, id, item, choice;
print_grocerylist(list, &index);
printf("Which item would you like to change?\nID number: ");
scanf("%d", &id);
printf("\nWhat do you want to change?\n1 - Grocery.\n2 - Amount.\n3 - Unit.\nChoose: ");
scanf("%d", &choice);
switch(choice){
case 1:
fflush(stdin);
printf("Grocery: ");
for(item = 0; item <= index; item++){
if(list[item].iD == id){
gets(list[item].grocery);
}
}
break;
case 2:
while(x == 0){
fflush(stdin);
printf("Amount: ");
for(item = 0; item <= index; item++){
if(list[item].iD == id){
x = scanf("%f", &list[item].amount);
}
}
if(x == 0){
puts("Error, please try again!");
}
}
break;
case 3:
fflush(stdin);
x = 0;
printf("Unit: ");
for(item = 0; item <= index; item++){
if(list[item].iD == id){
gets(list[item].unit);
if(isalpha(*list[item-1].unit)){
x = 1;
}else{
x = 0;
puts("Error: please try again!\n");
}
}
}
break;
default:
printf("\nError! Please try again.\n");
break;
}
return;
}
void remove_item(Grocery* list, int* index){ //Takes the last struct and copies it to the slot which will be "removed" and then reallocates the memory for the array -1, keeping the old ID, to make things simple.
int item;
printf("Which item would you like to remove?\nID number: ");
scanf("%d", &item);
strcpy(list[item].grocery, list[*index].grocery);
list[item].amount = list[*index].amount;
strcpy(list[item].unit, list[*index].unit);
list = realloc(list, (*index-1)*sizeof(Grocery));
return ;
}
For the most part, the "Grocery read_from_file()" function works, but it returns only the first item instead of the list it correctly read.
To return and assign (a pointer to) the whole list, change the call
*list = read_from_file(file_pointer, list, &index);
to
list = read_from_file(file_pointer, list, &index);
and the definition
Grocery read_from_file(FILE* file_pointer, Grocery* list, int* index){
…
return *list;
…
return *list;
}
to
Grocery *read_from_file(FILE *file_pointer, Grocery *list, int *index)
{
…
return list;
…
return list;
}
To not leak the memory of the old list when it reads one from a file, insert free(list) before list = (Grocery*)calloc(*index, sizeof(Grocery)); or change that to
list = realloc(list, *index * sizeof(Grocery));

Resources