Structures saved every second index value in C - c

I'm writing a project and have stumbled upon a problem.
My part has to take the entries and save them as a structure into the file. Everything seems to work properly until I try to save them. That's my get_db_entry code:
printf("Please enter a forename: ");
fflush(stdin);
fgets(st[index].forename, STRING_SIZE, stdin);
printf("Please enter a surname: ");
fflush(stdin);
fgets(st[index].surname, STRING_SIZE, stdin);
printf("Please enter an address: ");
fflush(stdin);
fgets(st[index].address, STRING_SIZE, stdin);
printf("Please enter plate number: ");
fflush(stdin);
fgets(st[index].plate_number, STRING_SIZE, stdin);
printf("Please enter account balance: ");
fflush(stdin);
scanf("%f", &st[index].balance);
And saving looks like this:
void save_db(struct customer *st){
FILE *pFile;
int file_nof=0;
FILE *pnof;
pnof=fopen("nof_db.dat", "rb");
fread(&file_nof, sizeof(int), 1, pnof);
fclose(pnof);
printf("File_nof value: %d\n", file_nof);
fflush(stdin);
if((pFile = fopen("database.dat", "ab")) != NULL) // Open file in write/update mode
{
fwrite(st, file_nof*sizeof(struct customer), 1, pFile);
fclose(pFile);
}
else
{
printf("Cannot open file");
exit(1);
}}
I've checked numerous times and the index value is being passed on correctly, meaning that it counts 0,1,2,etc.
The entries are being saved for 0,2,4,6, so there is literally a padding by an empty structure every entry, say: index=0 always saves properly, then index=1 - empty, though the program saves into index=2 automatically.
This leaves me with empty spaces and a waste of space.
There are multiple checks along the way that check the value of "index", so I've no idea what's going on.
PS.
file_nof = nof_entries = index+1

Related

How can I save a string with spaces to a file that should also be apart of a parallel array

int main (){
int id[ms],qid,score[ms],oscores[ms],menu,age[ms],nstud,i, dob[ms],a;
float stime[ms],ttime1[ms], cyctime[ms],ttime2[ms],runtime[ms],otime[ms];
float koswin = 0, ikidswin = 0, ciwin = 0, swimwin = 0, cycwin = 0, runwin =0;
char name[100][ms], sc[100][ms], etype[ms], gender [ms], kwin, iwin,
cwin,word[100],pname[100],psc[100];
FILE *fh;
FILE *fp;
fh=fopen("participants.txt","a");
printf("Would you like to:\n");
printf("1.Register participants\n");
printf("2.Access a participant's details\n");
scanf("%d",&menu);
system("cls");
if (menu == 1)
{
printf("Please enter number of participants you would like to register\n");
scanf("%d",&nstud);
for (i = 0; i < nstud; i++){
printf("Please enter the the ID number of the participant:\n");
scanf("%d",&id[i]);
printf("Please enter the participant's name:\n");
fgets(pname, sizeof(pname), stdin);
strcpy(sc[i], pname);
printf("Please enter the participant's School/Club:\n");
fgets(psc, sizeof(psc), stdin);
strcpy(sc[i], psc);
}
for (i= 0; i < nstud; i++ )
fprintf(fh,"\n%d\t\n%s\t",id[i],name[i]);
fclose(fh);
}
The code works up until I am to enter the name it skips over the name and goes to the school input but it doesn't even accept the school name. It continues by skipping another input. I first had scanf("%s", name[i]) and scanf("%s", sc[i]) and that worked perfectly but I wanted the user to be able to enter a space. So is there a way to accept a string that is apart of a parallel array with space and write it to a file?
The entry of the name looks skipped because the previous scanf()
for the entry of ID leaves the newline character in the input buffer
and the fgets() for the name reads it.
To avoid this, modify the line:
scanf("%d",&id[i]);
to
scanf("%d%*c",&id[i]);
to flush the input buffer.

How to count number of line from binary file for C programming

typedef struct {
int ID;
char name[30];
char position[20];
char department[20];
char password[10];
int contactnumber;
int age;
char emailaddress[30];
}admin;
admin info;
void registration() {
int count=1001,y;
FILE* Admin;
Admin = fopen("Admin_info.bin", "ab");
if (Admin == NULL) {
printf("Unable to open file");
}
printf("\tPlease insert your informantion below\n");
printf("\tID: ");
scanf("%d", &info.ID);
printf("\n\tName: ");
scanf("%s", &info.name);
printf("\tPosition: ");
rewind(stdin);
scanf("%s", &info.position);
printf("\tDepartment: ");
scanf("%s", &info.department);
printf("\tPassword: ");
scanf("%s", &info.password);
printf("\tContact Number: ");
scanf("%s", &info.contactnumber);
printf("\tAge: ");
scanf("%d", &info.age);
printf("\tEmail Address: ");
scanf("%s", &info.emailaddress);
fwrite(&info, sizeof(admin), 1, Admin);
}
*I wanted to auto generate the ID. Therefore, I need to read the number of line from binary file and add by 1 and I don't know how to read the number of line. Please someone help me
You should've mentioned that it's about the file you are writing to. And there are no actual lines, since you are writing binary data to it.
You could first open the file in rb mode, fseek with 0, SEEK_END, ftell to get the file size in bytes, close it again, then divide the file size by sizeof(admin) to get your ID. Then apply your code.
EDIT after comment by chux:
It is not necessary to first open the file in rb mode and close it, as I had suggested. It is sufficient to leave it open in ab mode as done in your code and just add the fseek and ftell. Depending on the system, even the fseek is not required, but this seems not to be guaranteed by the standard.
I just found a very much related question here: Problems getting ftell() in binary append

How to add line number to only a specific line in a file

I'm creating the inputs of a disease and information on it. The disease should have a number beside it but the remaining inputs should remain as is. How can i add the information to a file but have the disease number increment as it reads new inputs as the program closes?
I've tried using a variable to print the disease number as it goes, but i dont understand how to increment it.
void CreateNew(){
int diseasenum=1;
FILE*fptr;
fptr = fopen("Lifeline Medical & Diagnostic Center.txt", "a+");
if(fptr == NULL)
{
printf("Error! There is no file to write to. Please Create a file");
exit(1);
}
fflush(stdin);
printf("Enter the name of the disease you would like to give detail of: ");
gets(Dissarray.Disease);
if()
fprintf(fptr,"%d\tDisease: %s\n\n",diseasenum,Dissarray.Disease);
printf("\n");
fflush(stdin);
Dissarray.Lethality=0;
printf("What is the Lethality of %s?\t(Answer in percentage. Sample:90 OR 12, etc)\n",Dissarray.Disease);
if (scanf("%d", &Dissarray.Lethality)!= 1)
{
printf("This is not an appropriate number. Please enter appropriately.\n");
fflush(stdin);
scanf("%d", &Dissarray.Lethality);
}
fprintf(fptr,"Lethality: %d\n",Dissarray.Lethality);
printf("\n");
fflush(stdin);
printf("How is %s acquired. (Sample: Contagious Disease, STI, Hereditary)\n",Dissarray.Disease);
gets(Dissarray.ContagionFactor);
fprintf(fptr,"Contagion factor: %s\n",Dissarray.ContagionFactor);
printf("\n");
printf("How is %s Transmitted?\t\t(Sample: Airborne, Touch, Sex, Sneezing, etc.)\n",Dissarray.Disease);
gets(Dissarray.Spread);
fprintf(fptr,"Spread: %s\n",Dissarray.Spread);
printf("\n");
fflush(stdin);
Dissarray.Fatalities=0;
printf("On a yearly basis. What is the average Fatality count brought by %s?\t\t(How many have died to this disease? Sample:100000)\n",Dissarray.Disease);
if(scanf("%d", &Dissarray.Fatalities)!= 1)
{
printf("This is not an appropriate number. Please enter appropriately.\n");
fflush(stdin);
scanf("%d", &Dissarray.Fatalities);
}
fprintf(fptr,"Fatalities: %d\n",Dissarray.Fatalities);
printf("\n");
fflush(stdin);
printf("Has %s been known to evolve under any conditions?\n",Dissarray.Disease);
printf("What is the Sensitivity?\t\t(Sample:Temperatures over 90 degrees OR None.)\n");
gets(Dissarray.Sensitivity);
fprintf(fptr,"Sensitivity: %s\n\n",Dissarray.Sensitivity);
printf("\n");
printf("This ends the entry of info into the file\n");
fclose(fptr);
}
to answer your question about line numbering:
regarding:
int diseasenum=1;
change to:
static int diseasenum=1;
Then, before exiting the function:
diseasenum++;

Infinite loop on printing in the file

We were asked to store values from one file to another. (Reading it from a source txt file and copying it into another txt file) I got all the syntax correct but somehow, my program's got a logical error in printing in the second file (Infinite loop so that's why it won't proceed in the next while loop.) The product of this program is getting the last set of information entered only and the loop never ends.
Here's my program:
char ans;
FILE *fp,*fp2;
fp = fopen("INVENTORY.txt","w");
do{
printf("Date (mm/dd/yy): ");
scanf("%d %d %d", &inv.dt.m, &inv.dt.d, &inv.dt.yr);
printf("Part No.: ");
scanf("%d", &inv.pno);
printf("Price: ");
scanf("%f", &inv.price);
printf("Quantity On Hand: ");
scanf("%d", &inv.qty);
printf("Reorder Parts: ");
scanf("%d", &inv.rp);
printf("Monthly Order: ");
scanf("%d", &inv.mo);
if(inv.qty < inv.rp)
inv.oa = (inv.rp + inv.mo) - inv.qty;
else
inv.oa = 0;
fprintf(fp,"%d/%d/%d\t%d\t%.2f\t%d\t%d\t%d\t%.2f\n", inv.dt.m, inv.dt.d, inv.dt.yr, inv.pno, inv.price, inv.qty, inv.rp, inv.mo, inv.oa);
printf("Add another (Y/N)? ");
scanf(" %c",&ans);
printf("\n");
}while(ans == 'Y' || ans == 'y');
fclose(fp);
fp = fopen("INVENTORY.txt", "r");
fp2 = fopen("REPORT.txt", "w");
while(fscanf(fp,"%d/%d/%d\t%d\t%.2f\t%d\t%d\t%d\t%.2f\n", &inv.dt.m, &inv.dt.d, &inv.dt.yr, &inv.pno, &inv.price, &inv.qty, &inv.rp, &inv.mo, &inv.oa)!=EOF){
fprintf(fp2,"%d\t%.2f\t%d\t%d\t%d\t%.2f\n", inv.pno, inv.price, inv.qty, inv.rp, inv.mo, inv.oa);
}
fclose(fp);
fclose(fp2);
fp2 = fopen("REPORT.txt","r");
printf("Part No.\tPrice\tQuantity On Hand\tReorder Parts\tMonthly Order\tOrder Amount");
while(fscanf(fp2,"%d\t%.2f\t%d\t%d\t%d\t%.2f\n", &inv.pno, &inv.price, &inv.qty, &inv.rp, &inv.mo, &inv.oa)!=EOF){
printf("%d\t%.2f\t%d\t%d\t%d\t%.2f",inv.pno, inv.price, inv.qty, inv.rp, inv.mo, inv.oa);
}
fclose(fp2);
return 0;
I hope someone can help me with this, thank you.
Joven,
I think your problem lies with scanf(" %c",&ans); try removing the space infront of "%c"
The best thing for you to do would to be put some output at the end of your loops for debugging, you have a lot of loops, at the end of each loop do something like printf("\nwhile loop id: 1, seq: %d\n", loop_count) you also have some things going on with your fclose and fopens, Accesing files takes a small bit of time, it's quicker for you to open the file when you need it, and then close it when your done...If you need to read and write to a file at the same time use fopen(filename, "rw").

Block reading and writing using fread and fwrite in C

I am trying to read employee information from the user and enter it into a file using fwrite() function and later i want to print the data contents on the screen using fread() to read from file and then print it.
When i am inside the program, this process is working absolutely fine but after program is exited and i access the file where the information has been stored, i see unreadable characters but in the program they are printed as normal english characters and digits.
Here is my code:
#include<stdio.h>
struct emp{
int id;
char name[30];
double salary;
}S;
void main(){
char fname[60];
printf("Enter file name: ");
scanf("%s", fname);
FILE *fptr = fopen(fname, "a+"); // open file in append + mode, create if not found.
if(fptr == NULL){
printf("Some error occured !\n");
return;
}
int i, size;
printf("Enter the number of employees whose information is needed to be added to the file: ");
scanf("%d", &size);
// writing
for(i = 0 ; i < size ; i++){
printf("Employee %d:\n", i+1);
printf("Enter id: ");
scanf("%d", &S.id);
printf("Enter name: ");
while(getchar() != '\n'); // clear buffer
scanf("%s", S.name);
printf("Enter salary: ");
scanf("%lf", &S.salary);
fwrite(&S, sizeof(struct emp), 1, fptr);
printf("----------------------------------------\n");
}
rewind(fptr); // move pointer to first record in file
// reading
printf("File contents: \n");
printf("ID\t\tNAME\t\tSALARY\n");
while(fread(&S, sizeof(struct emp), 1, fptr) != 0){
printf("%d\t\t%s\t\t%lf\n", S.id, S.name, S.salary);
}
}
Here is the picture of what i am trying to expalin.
You are writing to the file the struct and not printing its contents separately. It works when you read it back, but when you open the file, it simply doesn't know what it is (you have int and char* and double in your struct.
If you want to visualize it on the file, you need to print each term of the struct individually, and read it back the same way, in order to see it on screen.

Resources