Search file and compare strings it contains with inputted variable - c

I'm trying to search a file containing information on a group of people, for example: their first name, last name and ID.
I'm prompting the user to enter their ID code. The program should search the text file and ensure that their code matches the one within the file so that the program can continue by comparing the string from the file and the variable inputted by the user.
I'm not sure how to implement this. Below is a snippet of the code:
#include <stdio.h>
#include <conio.h>
#include <string.h>
typedef struct record {
char (fname[3])[20];
char (lname[3])[20];
int code[3];
} information;
int main (void) {
char ffname[20], flname[20];
int fID, i;
FILE *kfile;
if ((kfile = fopen("C:\\Users\\Student\\Downloads\\information.txt","r")) == NULL) {
perror("Error while opening file");
} else {
printf("%-20s %-20s %s\n", "First Name", "Last Name", "ID");
fscanf(kfile, "%19s %19s %d", ffname, flname, &fID);
printf("\n");
while (!feof(kfile)) {
printf("%-20s %-20s %04d\n", ffname, flname, fID);
fscanf(kfile, "%19s %19s %d", ffname, flname, &fID);
}
fclose(kfile);
}
information info;
for (i = 0; i < 3; i++) {
printf("Please enter your ID.");
scanf("%04d", &info.code);
}
getch();
return 0;
}

I'm not sure I understand your problem, but you can try this:
typedef struct record {
char *fname;
char *lname;
int code;
} information;
int main (void) {
char ffname[28], flname[28];
int fID, i, id_;
information array[3];
FILE *kfile;
i = 0;
if ((kfile = fopen("C:\\Users\\Student\\Downloads\\information.txt","r")) == NULL) {
perror("Error while opening file");
} else {
while (!feof(kfile)) {
fscanf(kfile, "%s %s %d", ffname, flname, &fID);
array[i].fname = strdup(ffname);
array[i].lname = strdup(flname);
array[i].code = fID;
i++;
}
fclose(kfile);
}
printf("Please enter your ID: ");
scanf("%d", &id_);
for (i = 0; i < 3; i++) {
if (array[i].code == id_) {
// print the record
printf("%s %s \n", array[i].fname, array[i].lname);
}
}
return 0;
}

Related

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

Attempting to read file and save its content to a struct, not working

I have been trying to save register.txt contents to my main file and put it into a struct, it works until I try to print the actual struct. Somehow it doesn't go into it, like it does not save as an array, so the print I have written on the last line prints out what is on the register.txt file but the code does not save its contents as an array/struct in the main file. Any help is appreciated, thank you.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Anvandarnamn 100
#define Register 10
#define antalval 100
typedef struct {
char Fornamn[Anvandarnamn];
char Efternamn[Anvandarnamn];
int alder;
} agare;
typedef struct {
agare user;
char marke[Anvandarnamn];
char typ[Anvandarnamn];
char reg[6];
} fordon;
void Readfile(fordon bil[]) {
FILE *txt;
txt = fopen("Register.txt", "r");
int i;
for (i = 0; i < Register; i++) {
fscanf(txt, "%s %s %s %s %d %s",
bil[i].marke, bil[i].typ, bil[i].user.Fornamn,
bil[i].user.Efternamn, &bil[i].user.alder, bil[i].reg);
}
fclose(txt);
}
int main() {
fordon bil[Register];
Readfile(bil);
int raknare = 0;
int i = 0;
for (i = 0; i < 10; i++) {
printf("%s\t %s\t %s %s\t %d\t %s \n",
bil[i].marke, bil[i].typ, bil[i].user.Fornamn,
bil[i].user.Efternamn, bil[i].user.alder, bil[i].reg);
}
}
There are many reasons your code could fail: you should add some error testing.
test if fopen() succeeds and report failures with an explicit message that includes the filename.
test for fscanf() failure and report those.
Here is a modified version of ReadFile:
// pass the maximum count of records and return actual count
int Readfile(int count, fordon bil[]) {
FILE *txt;
int i;
txt = fopen("Register.txt", "r");
if (txt == NULL) {
fprintf(stderr, "cannot open Register.txt\n");
return -1;
}
for (i = 0; i < count; i++) {
// tell fscanf the maximum length of each string field
if (fscanf(txt, "%99s %99s %99s %99s %d %5s",
bil[i].marke, bil[i].typ, bil[i].user.Fornamn,
bil[i].user.Efternamn, &bil[i].user.alder, bil[i].reg) != 6) {
fprintf(stderr, "read failed for record %d\n", i + 1);
break;
}
}
fclose(txt);
return i;
}

i am getting some unreported values in my program

My program is to ask the user to enter the name and age of the person in his group. The number of person is not known to the user in the beginning of the program. The user keeps on entering the data till the user enters the age zero. The program finally prints the average age.
The source code is below
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct group {
char user_Name[21];
int user_age;
}Group;
int main()
{
Group *REC1;
FILE *out_file, *read_file;
int count_age=0, age, sum_age, i;
float avg_age;
char name[21]="", str[21]= "details.txt";
char sample_chr;
//opening a file in writing mode
out_file = fopen(str, "a");
// test for files not existing.
if (out_file == NULL)
{
printf("Error! Could not open file\n");
exit(-1); // must include stdlib.h
}
printf("\nEnter the Details of the person:\n\n");
do
{
printf("Enter the User Name:\n");
fflush(stdin);
scanf("%[^\n]",name);
printf("Enter the Age:\n");
fflush(stdin);
scanf("%d",&age);
if(age == 0)
{
break;
}
else
{
// write to file
fprintf(out_file,"%s,%d\n", name, age);
}
}while(1);
read_file = fopen(str,"r");
//counting the number of lines present in the above file
sample_chr = getc(read_file);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_age = count_age +1;
sample_chr = getc(read_file);
}
rewind(read_file);
//allocating space for array of structure dynamically
printf("\n%d\n",count_age);
count_age = count_age - 1;
REC1 = (Group*)malloc(count_age*sizeof(Group));
//storing the values in array of structures
for(i=0; i<=count_age; i++)
fscanf(read_file, "%s,%d", REC1[i].user_Name, &REC1[i].user_age);
fclose(read_file);
fclose(out_file);
for(i =0; i<=count_age; i++)
printf("\n%s %d\n", REC1[i].user_Name, REC1[i].user_age);
for(i=0, sum_age=0; i<=count_age; i++)
sum_age = sum_age + REC1[i].user_age;
avg_age = (float)sum_age/(count_age);
printf("\n\nThe average age is %f\n\n\n", avg_age);
system("pause");
return 0;
}
while i am compiling it doesn't shows any error. When i am running it shows exe file stopped working.
the following is working
there had to be changed the format in scanf() of name[] ( http://www.cplusplus.com/reference/cstdio/scanf/ )
, the fclose(out_file) had to be moved and the ending condition of the while loop had to be changed ...
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
typedef struct group {
char user_Name[21];
int user_age;
}Group;
int main()
{
Group *REC1;
FILE *out_file, *read_file;
int count_age=0, age, sum_age, i;
float avg_age;
char name[21]="", str[21]= "details.txt";
char sample_chr;
//opening a file in writing mode
out_file = fopen(str, "w");
// test for files not existing.
if (out_file == NULL)
{
printf("Error! Could not open file\n");
exit(-1); // must include stdlib.h
}
printf("\nEnter the Details of the person:\n\n");
do
{
printf("Enter the User Name:\n");
scanf("%21s[^\n]",name);
printf("Enter the Age:\n");
scanf("%d",&age);
if(age == 0)
{
break;
}
else
{
// write to file
fprintf(out_file,"%s , %d \n", name, age);
}
}while(age != 0);
fclose(out_file);
read_file = fopen(str,"r");
//counting the number of lines present in the above file
sample_chr = getc(read_file);
while (sample_chr != EOF)
{
if (sample_chr == '\n')
count_age = count_age +1;
sample_chr = getc(read_file);
}
rewind(read_file);
//allocating space for array of structure dynamically
printf("\n Number of group members : %d \n",count_age);
count_age = count_age - 1;
REC1 = (Group*)malloc(count_age*sizeof(Group));
//storing the values in array of structures
for(i=0; i<=count_age; i++)
fscanf(read_file, "%s , %d", REC1[i].user_Name, &REC1[i].user_age);
fclose(read_file);
for(i =0; i<=count_age; i++)
printf("\n Name : %s Age : %d \n", REC1[i].user_Name, REC1[i].user_age);
for(i=0, sum_age=0; i<=count_age; i++)
sum_age = sum_age + REC1[i].user_age;
avg_age = (float)sum_age/(count_age);
printf("\n\nThe average age is %f\n\n\n", avg_age);
return 0;
}

Display all men from a file on the screen in C

I'm a newbie in C.
Could you help me please. There is a structure First name, Last Name, gender, age. Entries must be entered from the keyboard. I need to save this information in a file and then show on the screen all entries with gender == Male and save them in a separate file.
Thank you!
There is a code for reading a structure from file, but I can't understand how to check gender == Male.
#include "stdafx.h"
#include <cstdio>
int _tmain(int argc, _TCHAR* argv[])
{
FILE *file;
struct Person {
char name[20];
char gender[20];
unsigned age;
};
struct Person SinglePerson[10];
char i=0;
file = fopen("e:\\Test.txt", "r");
while (fscanf (file, "%s%s%u", SinglePerson[i].name, &(SinglePerson[i].gender), &(SinglePerson[i].age)) != EOF) {
printf("%s %s %u\n", SinglePerson[i].name, SinglePerson[i].gender, SinglePerson[i].age);
i++;
}
file = fopen("e:\\fprintf.txt", "w");
while (scanf ("%s%s%u", SinglePerson[i].name, &(SinglePerson[i].gender), &(SinglePerson[i].age)) != EOF) {
fprintf(file, "%s %s %u\n", SinglePerson[i].name, SinglePerson[i].gender, SinglePerson[i].age);
i++;
}
fread;
return 0;
}
Worked! I did it ))
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define M 2 // M plus 1 is equals to number of structres
/* run this program using the console pauser or add your own getch, system("pause") or input loop */
FILE *file;
struct Person {
char name[20];
char gender[20];
unsigned age;
};
struct Person SinglePerson[1];
char i=0;
char counter = 0;
void InputFromKeyboard () {
file = fopen("Input.txt", "w");
while(scanf("%s%s%u", SinglePerson[i].name, SinglePerson[i].gender, &(SinglePerson[i].age)) == 3 && i <= M) {
fprintf(file, "%s %s %u\n", SinglePerson[i].name, SinglePerson[i].gender, SinglePerson[i].age);
counter++;
i++;
if (i == M+1) {
break;
}
}
fclose(file);
};
void OutputToFile () {
file = fopen("Output.txt", "w");
for (i = 0; i < counter; i++) {
if (strcmp(SinglePerson[i].gender, "Male") == 0) {
fprintf(file, "%s %s %u\n", SinglePerson[i].name, SinglePerson[i].gender, SinglePerson[i].age);
}
}
fclose(file);
}
void OutputToScreen () {
file = fopen("Output.txt", "r");
for (i = 0; i < counter; i++) {
if (strcmp(SinglePerson[i].gender, "Male") == 0) {
printf("%s %s %u\n", SinglePerson[i].name, SinglePerson[i].gender, SinglePerson[i].age);
}
}
fclose(file);
}
int main(int argc, char *argv[]) {
InputFromKeyboard();
OutputToFile();
OutputToScreen();
return 0;
}

How replace a string of a specific person in a file

I'm having a bit of problem. I've set the string 'Absent' to all student in a file. However, I want to replace 'Absent' with 'present' when the correct ID assigned to a student is entered. In other words, 'Absent' will only change to 'Present' for a specific person at a time. I'm not sure how to implement this and I'm asking kindly if someone would help. Thanks in advance.
UPDATE::====
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <errno.h>
typedef struct record {
char *fname;
char *lname;
int code;
char *stat;
} information;
int main (void) {
int i;
char ffname[28], flname[28], ans, status[15];
int fID, j, id_, x;
FILE *kfile, *ufile;
x = 0;
j = 0;
i = 0;
char buf[150];
time_t curtime;
struct tm* loc_time;
information array[100];
printf(" **********Attendance Recording System**********\n");
printf(" MENU \n");
//Getting current time of system
curtime = time (NULL);
// Converting current time to local time
loc_time = localtime (&curtime);
strftime (buf,150, "%I:%M %p.\n", loc_time);
//prints error message if file cannot be found within the system
if ((kfile = fopen("information.txt", "r")) == NULL) //If the file path is incorrect, an error message is displayed
{
fprintf(stderr, "Error while opening file (%d: %s)\n",errno, strerror(errno)); //Error message that will be displayed if file path is incorrect
return;
}
//while the file is opened and not at the end, the strings are stored into variables which forms an array of strings
for (x = 0; x < 200; x++) {
if (fscanf(kfile, "%s %s %d", ffname, flname, &fID) != 3) //Reads the contents of the file
break;
array[x].fname = strdup(ffname);
array[x].lname = strdup(flname);
array[x].code = fID;
}
fclose(kfile);
ufile= fopen("update.txt","w");
strcpy(status, "Absent");
fprintf(ufile,"First Name Last Name ID Status Time Arrived\n");
for (i = 0; i < x; i++) {
fprintf(ufile,"%-15s%-14s%2d%12s ",(array[i].fname), (array[i].lname), (array[i].code), status);
fprintf(ufile,"%16s",(buf));
}
fclose(ufile);
while(j < x){
printf("Enter you ID: ");
scanf("%d", &id_);
strcpy(status, "Absent");
bool isPresentInFile = false;
for(i=0; i<x; i++)
{
if(array[x].code == id_)
{
printf(" %s %s?", array[x].fname, array[x].lname);
isPresentInFile = true;
break;
}
}
if(isPresentInFile)
{
strcpy(status, "present");
}
j++;
}
fprintf(ufile,"First Name Last Name ID Status Time Arrived\n");
for (i = 0; i < x; i++) {
fprintf(ufile,"%-15s%-14s%2d%12s ",(array[i].fname), (array[i].lname), (array[i].code), status);
fprintf(ufile,"%16s",(buf));
}
fclose(ufile);
getch();
return 0;
}
UPDATE #3
#include <stdio.h>
#include <conio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
#include <time.h>
#include <errno.h>
typedef struct record {
char *fname;
char *lname;
int code;
} information;
int main (void) {
int i;
char ffname[28], flname[28], ans, ans1, status[15];
int fID, j, id_, x;
FILE *kfile, *ufile;
x = 0;
j = 0;
i = 0;
char buf[150];
time_t curtime;
struct tm* loc_time;
information array[100];
printf(" **********Attendance Recording System**********\n");
printf(" MENU \n");
//Getting current time of system
curtime = time (NULL);
// Converting current time to local time
loc_time = localtime (&curtime);
strftime (buf,150, "%I:%M %p.\n", loc_time);
//prints error message if file cannot be found within the system
if ((kfile = fopen("information.txt", "r")) == NULL) //If the file path is incorrect, an error message is displayed
{
fprintf(stderr, "Error while opening file (%d: %s)\n",errno, strerror(errno)); //Error message that will be displayed if file path is incorrect
return;
}
//while the file is opened and not at the end, the strings are stored into variables which forms an array of strings
for (x = 0; x < 200; x++) {
if (fscanf(kfile, "%s %s %d", ffname, flname, &fID) != 3) //Reads the contents of the file
break;
array[x].fname = strdup(ffname);
array[x].lname = strdup(flname);
array[x].code = fID;
}
fclose(kfile);
while(j < x){
Next:
printf("Enter you ID: ");
scanf("%d", &id_);
strcpy(status, "Absent");
bool isPresentInFile = false;
for(i=0; i<x; i++)
{
if(array[i].code == id_)
{
printf("Are you %s %s?", array[i].fname, array[i].lname);
printf("\n");
printf("[y/n only]: ");
scanf(" %c", &ans);
isPresentInFile = true;
break;
}//end of if statement
}//end of for loop
if(isPresentInFile)
{
strcpy(status, "present");
}//end of if statement
switch (ans){
case 'y':
ufile= fopen("update.txt","w");
fprintf(ufile,"First Name Last Name ID Status Time Arrived\n");
for (i = 0; i < x; i++) {
fprintf(ufile,"%-15s%-14s%2d%12s ",(array[i].fname), (array[i].lname), (array[i].code), status);
fprintf(ufile,"%16s",(buf));
}//end of for loop
fclose(ufile);
printf("Continue?\n");
printf("[y/n]: ");
scanf(" %c", &ans1);
if(ans1 == 'y'){
break;
}//end of if statements
else if (ans1 == 'n'){
exit(EXIT_SUCCESS);
}//end of else statement to check if ans1 is equal to 'n'
case 'n':
goto Next;
break;
default:
printf("invalid entry. Try again");
}//end of switch case statememt
j++;
}//end of while
getch();
return 0;
}
From your question, I didn't get when exactly do you want to change status from "Absent" to "present".
But you can use the same strcpy() method to overwrite your status variable.
...
strcpy(status, "Absent");
if(//condition)
{
strcpy(status, "present");
}
UPDATE 1:
After reading your comment, I understood that you will prompt the user to enter an ID. And if it matches with the ID present in the file, you need to update the status to "present" and then write to the new file.
I can think of something like this:
...
// read from file
.....
int ID;
printf("Enter you ID: ");
scanf("%d", &ID);
strcpy(status, "Absent");
bool isPresentInFile = false;
for(int i=0; i<x; ++i)
{
if(array[x].code == ID)
{
isPresentInFile = true;
break;
}
}
if(isPresentInFile)
{
strcpy(status, "present");
}
...
// write to file
.....
UPDATE 2:
After reading the updated question, I notice that you are writing to the file at the end! But overwriting the status variable each time. This way you end up writing either "Absent" or "Present" for all the entries in the file (Note that it pertains to the last candidate who enters his ID!)
To avoid this, do either of the following:
Write to the file as soon as you know the status of a candidate.
while(j < x)
{
printf("Enter you ID: ");
scanf("%d", &id_);
strcpy(status, "Absent");
bool isPresentInFile = false;
for(i=0; i<x; i++)
{
if(array[x].code == id_)
{
printf(" %s %s?", array[x].fname, array[x].lname);
isPresentInFile = true;
break;
}
}
if(isPresentInFile)
{
strcpy(status, "present");
}
// write to file here
j++;
}
Also have a field called status in the structure information.
By default, keep it "Absent" for all the candidates.
Then make it "Present" only for those who enter their IDs. Finally, write it to the file.

Resources