How to display a certain set of data File Handling C - c

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;
}

Related

Why is the while loop not executing to compare strings

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);
}

Username & Password don't match even if I input correctly

I am trying to create a program to enter into a system with username & password. But after creating the account, while in signin when I entered my username & password (stored from SignUP function), it shows incorrect. Where did I made the mistake and how can I fix it? I have given my specific code related to this problem. TIA
struct information
{
char username[20];
char password[20];
int date, month, year;
char pnumber[20];
int age[20];
char fname[20];
char lname[20];
char fathname[20];
char mothname[20];
char address[50];
};
void signup()
{
char username[20];
char password[20];
int passwordlength, i, seek = 0;
char ch;
FILE *fp, *fu;
struct information u1;
struct information p1;
// Opening file to
// write data of a user
fp = fopen("username.txt", "ab");
system("cls");
printf("\n\n!!!!!CREATE YOUR ACCOUNT!!!!!");
printf("\n\nFIRST NAME...");
scanf("%19s", u1.fname);
printf("\nLAST NAME...");
scanf("%19s", u1.lname);
printf("\nFATHER's NAME...");
scanf("%19s", u1.fathname);
printf("\nMOTHER's NAME...");
scanf("%19s", u1.mothname);
printf("\nADDRESS..");
scanf("%19s", u1.address);
printf("\nDATE OF BIRTH...");
printf("\nDATE-");
scanf("%d", &u1.date);
printf("\nMONTH-");
scanf("%d", &u1.month);
printf("\nYEAR-");
scanf("%d", &u1.year);
printf("\nPHONE NUMBER...");
scanf("%19s", u1.pnumber);
printf("\nAGE...");
scanf("%d", &u1.age);
printf("\nUSERNAME.. ");
scanf("%19s", u1.username);
printf("\nPASSWORD..");
scanf("%19s", p1.password);
fwrite(&u1, sizeof(u1), 1, fp);
fclose(fp);
printf("\n\nACCOUNT CREATED SUCCESSFULLY.\n");
char option[10];
printf("\nPRESS ANY KEY THEN ENTER TO GO TO SIGN IN PAGE");
scanf("%s", option);
signin();
}
void signin()
{
system("cls");
char username[20];
char password[20];
int i, j, k;
char ch;
FILE *fp, *fu;
struct information u1;
struct information p1;
// Opening file of
// user data
fp = fopen("username.txt","rb");
if (fp == NULL)
{
printf("\nERROR IN OPENING FILE\n");
printf("FILE DOESN'T EXIST\nYOU HAVE TO CREATE AN ACCOUNT FIRST\n");
printf("PRESS ANY KEY & ENTER TO CREATE AN ACCOUNT\n");
char option[10];
scanf("%s", option);
signup();
}
gotoxy(35, 10);
printf("==== LOG IN ====");
// Take input
gotoxy(35, 12);
printf("ENTER USERNAME.. ");
scanf("%19s", username);
gotoxy(35, 14);
printf("ENTER PASSWORD.. ");
scanf("%19s", password);
// Checking if username & password
// exists in the file or not
while (fread(&u1, sizeof(u1), 1, fp))
{
if (strcmp(username, u1.username) == 0)
if (strcmp(password, u1.password) == 0)
{
mainmenu();
}
fclose(fp);
}
In the signup() function you are reading the password into the p1.password field, but then only writing the u1 struct to the file. Simply change scanf("%19s", p1.password); to scanf("%19s", u1.password);.

Scan (read) from BIN file

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);
}

Chinese characters show up on txt file after fwrite

I want to write data in structure to a text file. But it ends up showing strange characters in the text file. I have changed many forms of fwrite arguments but none works. Please someone help me. Sorry for the long code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Student
{
char name[30];
int id;
int score;
int score2;
int score3;
};
int main()
{
printf("Please input the information below into grade.data!\n");
printf("Ends with name's value equal to 'E'\n");
struct Student stu[10];
int i = 0, maxlength = 0; //size of longest name
printf("Name No Math Chi Eng\n");
while (true){
scanf("%s", stu[i].name);
if(maxlength < strlen(stu[i].name)) maxlength = strlen(stu[i].name);
if (stu[i].name[0] == 'E') break;
scanf("%d", &stu[i].id);
scanf("%d", &stu[i].score1);
scanf("%d", &stu[i].score2);
scanf("%d", &stu[i].score3);
i++;
}
FILE* fp;
fp = fopen("test.txt", "wb");
if (fp == NULL) {
printf("Open file error!");
exit(-1);
}
fwrite(&stu, sizeof(struct Student), 1, fp);
fclose(fp);
printf("Name%-*c No%-*c Math Chi Eng\n", maxlength-4, ' ', 7, ' ');
for (int i = 0; stu[i].name[0] != 'E'; i++) {
printf("%-*s ", maxlength, stu[i].name);
printf("%-*d ", 9, stu[i].id);
printf("%-*d ", 4, stu[i].score1);
printf("%-*d ", 3, stu[i].score2);
printf("%d\n", stu[i].score3);
}
return 0;
}
It because members in the structure Student other than name are integers. Convert integer values to ASCII and then store it in the file.

C doesn't load info from file (fread, fwrite)

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLENG 50 //just a random value
typedef struct Song
{
char *name;
char *nameSong;
char *timeSong;
int date;
} Song;
void saveToFile(Song *x, int *songCount) //Saves info to the binary file
{
FILE *f = fopen("array.txt", "w");
if (f == NULL)
{
printf("Error\n");
}
fwrite(songCount, sizeof(int), 1, f);
fwrite(x, sizeof(struct Song), (*songCount), f);
fclose(f);
}
void readSong(Song *x, int *songCount) //Reads info fromt he file and writes it
{
FILE *fr = fopen("array.txt", "r");
if (fr == NULL)
{
printf("Error\n");
}
printf("Songs:\n");
fread(songCount, sizeof(int), 1, fr);
fread(x, sizeof(struct Song), (*songCount), fr);
for(int i=0; i < (*songCount); i++)
{
printf("%d. %s %s %s %d\n", (i+1), x[i].name, x[i].nameSong, x[i].timeSong, x[i].date);
}
fclose(fr);
}
void insertSong(Song *x, int Count) //Inserts new song into the array.
{
printf("\nInsert name of the band:\n");
x[Count].name=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].name);
printf("Insert name of the song:\n");
x[Count].nameSong=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].nameSong);
printf("Insert length of the song:\n");
x[Count].timeSong=malloc(SLENG * sizeof(char));
scanf("%s", x[Count].timeSong);
printf("Insert then song was created:\n");
scanf("%d", &(x[Count].date));
printf("\n");
}
main()
{
int songCount, menuOption;
Song *x=malloc(SLENG*sizeof(char)+SLENG*sizeof(char)+SLENG*sizeof(char)+sizeof(int));
printf("1. insert song\n 2. load from file\n ");
scanf("%d", &menuOption);
switch(menuOption)
{
case(1) :
printf("Insert how many songs do you want to input?\n");
scanf("%d", &songCount);
for(int i=0; i<songCount; i++)
{
insertSong(x, i);
}
saveToFile(x, &songCount);
break;
case(2) :
readSong(x, &songCount);
break;
}
}
I have an assingment to write a programm which would input some data into file and could read that data from that file, the problem is probably with fwrite or fread, couse it seems to crash everytime I try to load the and write the data from file. Any ideas why is it not working properly? And can I even do it like this as it is dynamic struct array. Thanks in advance.
In order to save the structure to a file, it must only contain scalar values, not pointers into memory objects. Modify your structure to use arrays instead of pointers:
typedef struct Song {
char name[SLENG];
char nameSong[SLENG];
char timeSong[SLENG];
int date;
} Song;
And modify the code accordingly, but note that:
saving and reading the structures to and from a file requires opening it in binary mode "wb" and "rb".
it is very misleading to name a binary file array.txt.
you do not need to pass the address of the count when writing to the file, but you need to pass the address of the array pointer when reading as you do not know yet how much memory to allocate.
Here is the modified code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define SLENG 50 // this value is used in the file format
typedef struct Song {
char name[SLENG];
char nameSong[SLENG];
char timeSong[SLENG];
int date;
} Song;
int saveToFile(Song *x, int songCount) { //Saves info to the binary file
FILE *f = fopen("array.bin", "wb");
if (f == NULL) {
printf("Error\n");
return -1;
}
fwrite(songCount, sizeof(int), 1, f);
int written = fwrite(x, sizeof(struct Song), songCount, f);
fclose(f);
return written;
}
int readSong(Song **x, int *songCount) { //Reads info from the file and writes it
int count = 0;
FILE *fr = fopen("array.bin", "rb");
if (fr == NULL) {
printf("Error\n");
return -1;
}
printf("Songs:\n");
fread(&count, sizeof(int), 1, fr);
*x = calloc(count, sizeof(Song));
if (*x == NULL) {
printf("Cannot allocate %d bytes of memory\n", count);
fclose(fr);
return -1;
}
int found = fread(*x, sizeof(struct Song), count, fr);
for (int i = 0; i < found; i++) {
printf("%d. %s %s %s %d\n", i + 1,
(*x)[i].name, (*x)[i].nameSong, (*x)[i].timeSong, (*x)[i].date);
}
fclose(fr);
return *songCount = found;
}
void insertSong(Song *x, int Count) { //Inserts new song into the array.
printf("\nInsert name of the band:\n");
scanf("%49s", x[Count].name);
printf("Insert name of the song:\n");
scanf("%49s", x[Count].nameSong);
printf("Insert length of the song:\n");
scanf("%49s", x[Count].timeSong);
printf("Insert then song was created:\n");
scanf("%d", &(x[Count].date));
printf("\n");
}
int main(void) {
int songCount, menuOption;
Song *x = NULL;
printf("1. insert song\n 2. load from file\n ");
scanf("%d", &menuOption);
switch (menuOption) {
case 1:
printf("Insert how many songs do you want to input?\n");
if (scanf("%d", &songCount) == 1) {
x = calloc(songCount, sizeof(Song));
for (int i = 0; i < songCount; i++) {
insertSong(x, i);
}
saveToFile(x, songCount);
}
break;
case 2:
readSong(&x, &songCount);
break;
}
free(x);
x = NULL;
return 0;
}

Resources