First, the while loop is not comparing titles in the file and the num_books does not add on top of the file. Second, instead of reading the num_books already in the file, it reads twice every time executed. can someone help?
typedef struct book {
char *title;
char *author;
char *subject;
};
struct library {
struct book collection;
int num_books;
struct library *next;
};
add(FILE *file, FILE *fileout, struct library *thislib, struct book *thisbook) {
char choice = "1";
int size;
char line1[50];
file = fopen("temp1.txt", "a+");
fileout = fopen("temp2.txt", "a+");
printf("\t Add a book to your library!\n");
printf("\t\t Title: ");
scanf("%s", &thisbook->title);
printf("\t\t Author: ");
scanf("%s", &thisbook->author);
printf("\t\t Subject: ");
scanf("%s", &thisbook->subject);
fseek(file, 0, SEEK_SET);
thislib->num_books++;
fprintf(file, "%d", thislib->num_books);
size = ftell(file);
while (thislib->num_books > 1) {
for (int i = 1; i < size; i++) {
fseek(file, i, SEEK_CUR);
fscanf(file, "%s", line1);
printf("%s", line1);
if (strcmp(thisbook->title, line1) != 0) {
printf("Please re-enter title as similar ones are not allowed.\n");
printf("\t\t Title: ");
scanf("%s", &thisbook->title);
strcpy(line1, "");
}
}
}
fseek(file, 1, SEEK_SET);
fprintf(file, "%c %s %s %s\n", choice, &thisbook->title, &thisbook->author, &thisbook->subject);
fprintf(fileout, "The book %s, author %s, subject %s has been added to the library.\n", &thisbook->title, &thisbook->author, &thisbook->subject);
fclose(file);
fclose(fileout);
}
Related
I need to solve a problem. I need to create two functions which scan user's input information and put in into structure array and then put all array to BIN file (with function fwrite()) and other function - read from BIN file with function fread(). You can see my code below. Problem is that I can write to file, but when I read I get filler array element and other element which are empty. How to get only filled struct array element?
#include <stdio.h>
#include <stdlib.h>
#include <mem.h>
typedef struct
{
char Lesson[50];
char TeachersName[50];
char TeachersLastName[50];
int Credits;
int NumberOfStudents;
} School;
void ToFile (char *fileName);
void FromFile (char *FileName);
int main()
{
char *fileName[]={"student.bin"};
ToFile (*fileName);
FromFile (*fileName);
return 0;
}
void ToFile (char *fileName)
{
int n, chars;
FILE *fp;
fp = fopen(fileName, "wb");
School Info[20];
if(fp == NULL)
{
printf("Error opening file\n");
exit(1);
}
printf("Testing fwrite() function: \n\n");
printf("Enter the number of records you want to enter: ");
scanf("%d", &n);
for(int i = 0;i<n;i++)
{
printf("\nEnter details of employee %d \n", i + 1);
fflush(stdin);
printf("Lesson: ");
gets(Info[i].Lesson);
printf("Teachers name: ");
gets(Info[i].TeachersName);
printf("Teachers last name: ");
gets(Info[i].TeachersLastName);
printf("Credits: ");
scanf("%d", &Info[i].Credits);
printf("Number of studens: ");
scanf("%d", &Info[i].NumberOfStudents);
chars = fwrite(&Info[i], sizeof(Info), 1, fp);
printf("Number of items written to the file: %d\n", chars);
}
fclose(fp);
}
void FromFile (char *FileName)
{
School Info[20]= { { "", "","",0,0 } };;
FILE * fpp;
fpp = fopen(FileName, "rb");
fread(&Info, sizeof(Info), 1, fpp);
/*
for(int j=0; j<20; ++j) {
printf("\nLesson: %s", Info[j].Lesson);
printf("\nTeachers name: %s", Info[j].TeachersName);
printf("\nTeachers last name: %s", Info[j].TeachersLastName);
printf("\nCredits: %d", Info[j].Credits);
printf("\nNumber of students: %d", Info[j].NumberOfStudents);
printf("\n");
}*/
int j=0;
while (fread(&Info, sizeof(Info), 1, fpp))
{
printf("\nLesson: %s", Info[j].Lesson);
printf("\nTeachers name: %s", Info[j].TeachersName);
printf("\nTeachers last name: %s", Info[j].TeachersLastName);
printf("\nCredits: %d", Info[j].Credits);
printf("\nNumber of students: %d", Info[j].NumberOfStudents);
printf("\n");
j++;
}
fclose(fpp);
}
I have a code where I am able to add my struct array to a file, but am unable to continue adding contacts to my struct array like I should.
Here are my variables:
struct contact { // Data structure that holds contact information
char FirstName[10]; // Array for first name
char LastName[10]; // Array for last name
int PhoneNum; // Phone number
};
int Choice = 0;
int n = 0;
int size = 1;
struct contact *con = (struct contact *)malloc(size * sizeof(struct contact));
int a = 0;
int b = 0;
int SortChoice = 0;
int iRandNum = 0;
int Valid = 0;
char temp[10];
int tempNum = 0;
char File[20];
int status = 0;
FILE *pRead;
FILE *pWrite;
Here is the add contact part:
if (n == size)
{
size = size * 2;
con = (struct contact*)realloc(con, size * sizeof(struct contact));
}
// Records the information given into the structure
printf("\nYou chose to add a contact.");
printf("\nFirst name: ");
scanf("%s", con[n].FirstName);
printf("\nLast name: ");
scanf("%s", con[n].LastName);
printf("\nPhone number (Numbers only): ");
scanf("%d", &con[n].PhoneNum);
printf("\nRecord added to the phone book.");
// Prints out the given information
printf("\n\nNew contact:");
printf("\nFirst name: %s", con[n].FirstName);
printf("\nLast name: %s", con[n].LastName);
printf("\nPhone number: %d", con[n].PhoneNum);
printf("\nContact number is %d", n);
printf("\n");
n += 1;
And here is the file part:
printf("\nYou chose to store all contacts to a file.");
if (status == 0){
printf("\nWhat would you like to name your file?\n");
scanf("%s", &File);
printf("\nFile name is %s", File);
pWrite = fopen(File, "w");
if (pWrite == 0){
printf("\nFile not opened");
}
else {
for (a = 0; a < n; a++){
fwrite(&con[a], sizeof(struct contact), 1, pWrite);
}
fclose(pWrite);
pRead =fopen(File, "r");
printf("\n\nContacts added to %s", File);
printf("\n\nContacts in file:\n");
while (fread(&con[a], sizeof(struct contact),1, pRead)){
printf("\n");
printf("\nFirst name: %s", con[a].FirstName);
printf("\nLast name: %s", con[a].LastName);
printf("\nPhone number: %d", con[a].PhoneNum);
printf("\n");
}
fclose(pRead);
}
}
If you guys can figure out where I've gone wrong, and potentially why I can't continue to access the file I created that would be great. Thanks
so I am thinking if there's a way that I could display one set of data inputted. So my sample program operates like this:
The user inputs a name, gender, and an age. The user can input multiple data. But I want to add a function where the user will type in a name, and then displays the name, and its corresponding gender, and age. But the thing is, I have no idea to do that. I heard of a function fseek() but I think it just edits the value; for example, age or gender.
Here is my sample code:
#include <stdio.h>
#include <stdlib.h>
struct clientName {
char name[30];
char gender[10];
};
struct clientAge {
int age;
};
void main() {
FILE *fp;
fp = fopen("data.txt", "ab");
struct clientName NAME;
struct clientAge AGE;
if(fp == NULL){
printf("Error");
getch();
} else {
system("cls");
printf("Enter Name: ");
gets(NAME.name);
printf("Enter Gender: ");
gets(NAME.gender);
printf("Enter Age: ");
scanf("%d", &AGE.age);
fwrite((char *)&NAME, sizeof(struct clientName), 1, fp);
fwrite((char *)&AGE, sizeof(struct clientAge), 1, fp);
printf("\n\nData Added");
fclose(fp);
}
system("cls");
fp = fopen("data.txt", "rb");
while((fread((char *)&NAME, sizeof(struct clientName), 1, fp)) == 1 & (fread((char *)&AGE, sizeof(struct clientAge), 1, fp)) == 1) {
printf("%s", NAME.name);
printf(" %s", NAME.gender);
printf(" %d y/o", AGE.age);
printf("\n");
}
fclose(fp);
}
There are a couple of problems i see with your code. I'll first try to correct it and then provide a full example of how I would do what you want done.
struct clientName {
char name[30];
char gender[10];
};
struct clientAge {
int age;
};
Why are you using 2 structs for 1 dataset?
Use
struct data
{
char name[30];
char gender[10];
int age;
};
instead.
fwrite((char *)&NAME, sizeof(struct clientName), 1, fp);
can be written as: fwrite(&client, sizeof(client), 1, fp);
while((fread((char *)&NAME, sizeof(struct clientName), 1, fp)) == 1
& (fread((char *)&AGE, sizeof(struct clientAge), 1, fp)) == 1)
can be written as: while (fread(&client, sizeof(client), 1, fp))
after which you only have to compare the client.name variable with your user input name like so:
if (strcmp(client.name, input) == 0)
Please note that I only opted to use one struct on purpose, as I do not see why it would be beneficial to use 2 structs in your use case.
If you, however do need to use 2 structs you can simply add an 'ID' integer variable to both of them and find all data points to any given name that way.
Full code example:
struct data
{
char name[30];
char gender[10];
int age;
};
int main(void)
{
struct data client;
FILE* fp;
char ch = 0;
do
{
printf("Enter Name: ");
scanf("%s", client.name);
printf("Enter Gender: ");
scanf("%s", client.gender);
printf("Enter Age: ");
scanf("%d", &client.age);
fp = fopen("Data.dat", "ab");
fwrite(&client, sizeof(client), 1, fp);
fclose(fp);
printf("continue? \n");
scanf(" %c", &ch);
} while (ch != 'n'); // continuously appends file till letter n is read;
char input[30]; // user input
printf("name?\n"); // please note that you could pretty much use every other data point here.
scanf("%s", input);
struct data Read; // used different for showcasing purposes only
fp = fopen("Data.dat", "rb");
while (fread(&client, sizeof(client), 1, fp))
{
if (strcmp(client.name, input) == 0) // compare variable with user input
{
printf("%s", client.name);
printf(" %s", client.gender);
printf(" %d y/o", client.age);
printf("\n");
}
}
return 0;
}
In the code below I'm trying to insert, display and delete data from a file.txt. I'm being able to insert successfully but my display function do not display correct and I don't know how to set up the logic to make the delete function. I would appreciate some help in changing the code so it can works. How can I set up the logic for it?
#include <stdio.h>
void menu() {
printf("Option 1 - Create a file and insert data:\n");
printf("Option 2 - Read file and display:\n");
printf("Option 3 - Delete content:\n");
printf("Option 4 - Exit:\n");
};
struct Book {
char title[256];
char author[256];
int pages;
int price;
};
void get() {
struct Book *book;
book = (struct Book*)malloc(sizeof(struct Book));
FILE *fPtr;
fPtr = fopen("file.txt", "w");
if (fPtr == NULL) {
printf("Fail creating file");
getch();
exit(1);
};
for (int i = 0; i < 1; i++) {
printf("Enter the book title:\n");
scanf("%s", &book[i].title);
fprintf(fPtr, "Title = %s", book[i].title);
printf("Enter the author of the book:\n");
scanf("%s", &book[i].author);
fprintf(fPtr, "Author = %s", book[i].author);
printf("Enter the number of pages:\n");
scanf("%d", &book[i].pages);
fprintf(fPtr, "Pages = %d", book[i].pages);
printf("Enter the price:\n");
scanf("%d", &book[i].price);
fprintf(fPtr, "Price = %d", book[i].price);
};
/*for (int i = 0; i < 1; i++) {
printf("%s\n", book[i].title);
printf("%s\n", book[i].author);
printf("%d\n", book[i].pages);
printf("%d\n", book[i].price);
};*/
fclose(fPtr);
};
void display() {
FILE *fPtr;
fPtr = fopen("file.txt", "r");
printf("The content of file are:\n", fPtr);
/*struct Book *book;
book = (struct Book*)malloc(sizeof(struct Book));
printf("%s %s %d %d", book.title, book.author, book.pages, book.price);*/
free(book);
fclose(fPtr);
}
int main()
{
int opt = 0;
int opt2 = 0;
int var = 0;
int validation = 0;
while (opt != 4) {
menu();
do
{
printf("Choose an option:\n");
validation = scanf_s("%d", &opt);
while (getchar() != '\n');
} while (validation != 1);
switch (opt) {
case 1:
get();
printf("Option 5 - Display data:\n");
printf("Option 6 - Delete:\n");
scanf("%d", &var);
if (var == 5) {
//FILE *fp1;
/*fp1 = fopen("file.txt", "r");*/
display();
}
else if (var == 6) {
printf("delete!");
}
break;
case 2:
printf("First insert data:\n");
break;
case 3:
printf("First insert data:\n");
break;
case 4:
return 0;
}
}
}
note : display() proposal 2
void display() {
FILE *fp;
fp = fopen("file.txt", "r");
struct Book book;
printf("%s %s %d %d", book.title, book.author, book.pages, book.price);
free(book);
fclose(fp);
}
I encourage you to rename Books to Book because that struct manages one book, not several.
About the command codes to enter, rather than 1 .. 4 what about 'c' for create, 'r' for read, 'd' for delete and 'e' for exit ?
Concerning get() :
you have a memory leak because the allocated Books is not freed. This allocation is useless, better to have struct Book book;
for (int i = 0; i < 1; i++) is useless and equivalent to int i = 0, do you really manages only 1 book ?
in your fprintf move the '\n' from the beginning to the end, else your file starts by an empty line and the last line is not ended
Is it necessary to prefix each data by its kind like Title = ? To read the file content is more complex with these prefixes
Concerning display() :
you do not read the content of the file, so difficult do display it :)
you allocate a Books, do not initialize it, but write its( uninitialized) fields
for (int i = 0; i < 1; i++) is useless and equivalent to int i = 0
you have a memory leak because the allocated Books is not freed. This allocation is useless, better to have struct Book book;
Concerning display() :
you do not read the content of the file, so difficult do display it :)
you allocate a Books, do not initialize it, but write its( uninitialized) fields
for (int i = 0; i < 1; i++) is useless and equivalent to int i = 0
you have a memory leak because the allocated Books is not freed. This allocation is useless, better to have struct Book book;
Concerning deleteStudentRecord() :
getNoOfRecords() is not defined, but currently it must return 1 because you manage only one book in the file
var is not defined, nor ptr
open file2 with "w", it is a new file
fread(&var, sizeof(struct student), 1, ptr) is wrong because it supposes a line has always sizeof(struct student) but this is not the case refering to get()
fcloseall() ??? just do fclose(ptr); and fclose(ptr2), rename them fpIn and fpOut or something like will make your code more readable
"get(); proposal 2"
void get() {
FILE *fPtr;
fPtr = fopen("file.txt", "w");
struct Book book;
if (fPtr == NULL) {
printf("Fail creating file");
getch();
exit(1);
};
printf("Enter the book title:\n");
scanf("%s", &book.title);
fprintf(fPtr, "%s", book.title);
printf("Enter the author of the book:\n");
scanf("%s", &book.author);
fprintf(fPtr, "%s", book.author);
printf("Enter the number of pages:\n");
scanf("%d", &book.pages);
fprintf(fPtr, "%d", book.pages);
printf("Enter the price:\n");
scanf("%d", &book.price);
fprintf(fPtr, "%d", book.price);
/*for (int i = 0; i < 1; i++) {
printf("%s\n", book[i].title);
printf("%s\n", book[i].author);
printf("%d\n", book[i].pages);
printf("%d\n", book[i].price);
};*/
fclose(fPtr);
};
everyone.so I have this binary file with data written to it using an array of structures. Now I want to update a specific record in it. however, i am unsure of how to achieve this based on using fseek. Could anyone please offer some assistance?
struct clientData{
char cliName[16];
char persIdNum[10];
int pos;
char empID[6];
};
FILE* fptr;
//FILE* f;
char compName[15];
printf("Enter company name: ");
scanf(" %s", compName);
fptr = fopen(strcat(compName,".dat"), "wb");
struct clientData data[5];
int i;
for(i=0; i<5; i++){
data[i].pos = i;
printf("\nEnter client name %d: ", i+1);
scanf(" %s", data[i].cliName);
printf("\nEnter client personal id %d: ", i+1);
scanf(" %s", data[i].persIdNum);
printf("\nEnter employee ID %d: ", i+1);
scanf(" %s", data[i].empID);
}
fwrite(data, sizeof(struct clientData), 5, fptr);
fclose(fptr);
///////////////////////////////////////////////////////////////////////////////////////////////////////
FILE *fptr;
struct clientData info[5];
fptr = fopen(CmpName, "rb+");
if (fptr == NULL)
printf("eRROR OPENING");
do {
system("cls");
printf("\n\t\t\t CLIENTS IN FILE: %s ", CmpName);
for(i=0; i<5; i++){
fread(info, sizeof(struct clientData), 5, fptr);
printf("\n\n\t\t\t\t%d %s", info[i].pos+1, info[i].cliName);
}
printf("\n\t\t******************************************************");
printf("\n\n\t\t\tSelect client name to be updated: ");
scanf(" %d", &CliName);
if(CliName >=1 && CliName <=5 ){
correct = true;
for(i=0; i<5; i++){
fread(info, sizeof(struct clientData), 5, fptr);
/*i want to fseek to the positon of the data selected above by the user.
where should i put it?*/
printf("\n\n\t\t\tEnter New Client Name:");;
scanf(" %s", NewCliName);
printf("\n\n\t\t\tEnter New Client Personal ID:");;
scanf(" %s", NewCliPersID);
strcpy(info[i].cliName, NewCliName);
strcpy(info[i].persIdNum, NewCliPersID);
fwrite(info, sizeof(struct clientData), 5, fptr);
break;
}//END OF FOR LOOP
Use
fseek(fptr,sizeof(struct clientData)*(CliName-1),SEEK_SET)