I'm wondering if I could use fseek() on editing the value of a variable on a file. All the tutorials I saw online were about editing a text, but how can I use fseek() to edit a value.
Here's how my program works: The user inputs a name, gender, and age. The user can input as many data as they want. Now, the user searches a name; and the gender, and age of that name will display. The user is then prompted to edit the age. After inputting a new age, the file will now be edited, with the new age written.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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.txt", "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");
scanf("%s", input);
struct data Read;
fp = fopen("data.txt", "rb");
int newAge;
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");
printf("enter new age");
scanf("%d", &newAge);
//fseek function
}
}
return 0;
}
Hope somebody can help.
Related
I am creating a task management system where the user can add,modify and delete their tasks. But I am facing errors with modifying elements in a line in a file.
This is where I add tasks to the file:
void add_task()
{
int id;
char name[50];
char category[50];
char info[50];
char date[20];
char status[20];
char another = 'Y';
FILE *fptr;
fptr = fopen("Tasks.txt","r+");
if (fptr==NULL)
{
printf("\nSYSTEM ERROR");
fptr = fopen("Tasks.txt","w");
getchar();
return;
}
while (another == 'Y'|| another == 'y')
{
fseek(fptr,0,SEEK_END);
printf("\nTo Add a new task enter the details below\n");
printf("Enter an ID to identify your tasks easily(LESS THAN 5 CHAR):");
scanf("%d",&id);
printf("Name of Task:");
getchar();
fgets(name,50,stdin);
name[strcspn (name, "\n")] = 0;
printf("Category of Task:");
fgets(category,50,stdin);
category[strcspn (category, "\n")] = 0;
printf("Information about task(Max 49 characters):");
fgets(info, 50, stdin);
info[strcspn (info, "\n")] = 0;
printf("Due Date of Task(yyyy/mm/dd):");
scanf(" %s", date);
printf("Status of Task\n TD = To-Do\n IP = In Progress\n CT = Completed Task\nEnter Status:");
scanf(" %s", status);
fprintf(fptr,"%d %s %s %s %s %s\n",id, name, category, info, date, status);
printf("\nDo you want to add another record (Y/N)");
fflush(stdin);
another = getchar();
}
fclose(fptr);
printf("\n\n\tPress any key to exit");
exit(0);
}
This is where I want to change only the category of the task but it changes the name instead:
void change_category()
{
int id;
char name[50];
char category[50];
char info[50];
char date[20];
char status[20];
int i;
FILE * fptr = fopen("Tasks.txt","r");
FILE * fp = fopen("temp.txt","w");
printf("Enter the ID of the task you want to update:");
scanf("%d",&id);
while(fscanf(fptr,"%d",&i) != EOF)
{
fscanf(fptr,"%s",category);
fgets(info,50,fptr);
if(i == id)
{
printf("Task Found");
printf("\nUpdating category for task with ID: %d",id);
printf("\nEnter new category:");
scanf("%s",category);
}
fprintf(fp,"%d %s %s\n",i,category,info);
}
fclose(fp);
fclose(fptr);
remove("Tasks.txt");
rename("temp.txt","Tasks.txt");
}
Sample entry into the file:
8291 Math Math HW Pg 1-2 2022/04/03 IP
Update Category entry:
English
Updated File:
8291 English Math HW Pg 1-2 2022/04/03 IP
I'm new to C and trying to write a program for a hotel and let customers edit their booking details such as first name, last name...etc. The code I wrote can be run but the data in the file is not edited.
The else statement for the line ("Record not found! Please enter your Username and Password again.\n"); is not printed when I entered the wrong username and password as well.
Here is what I got so far:
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdbool.h>
struct customer_details // Structure declaration
{
char uname[100];
char pass[100];
char fname[100];
char lname[100];
char ic[100];
char contact[100];
char email[100];
char room[100];
char day[100];
}s;
void main()
{
FILE* f, *f1;
f = fopen("update.txt", "r");
f1 = fopen("temp.txt", "w");
char uname[100], pass[100];
int valid = 0;
// validate whether file can be opened.
if (f == NULL)
{
printf("Error opening file!\n");
exit(0);
}
printf("Please enter your Username and Password to update your booking detail.\n");
printf("\nUsername: ");
fgets(uname, 100, stdin);
uname[strcspn(uname, "\n")] = 0;
printf("Password: ");
fgets(pass, 100, stdin);
pass[strcspn(pass, "\n")] = 0;
while (fscanf(f, "%s %s", s.uname, s.pass) != -1)
{
if (strcmp(uname, s.uname) == 0 && strcmp(pass, s.pass) == 0)
{
valid = 1;
fflush(stdin);
printf("Record found!\n");
printf("\nEnter First Name: ");
scanf("%s", &s.fname);
printf("\nEnter Last Name: ");
scanf("%s", &s.lname);
printf("\nEnter IC Number: ");
scanf("%s", &s.ic);
printf("\nEnter Contact Number:");
scanf("%s", &s.contact);
printf("\nEnter Email: ");
scanf("%s", &s.email);
printf("\nEnter Room ID :");
scanf("%s", &s.room);
printf("\nEnter Days of staying:");
scanf("%s", &s.day);
fseek(f, sizeof(s), SEEK_CUR); //to go to desired position infile
fwrite(&s, sizeof(s), 1, f1);
}
else
("Record not found! Please enter your Username and Password again.\n");
}
fclose(f);
fclose(f1);
if (valid == 1)
{
f = fopen("update.txt", "r");
f1 = fopen("temp.txt", "w");
while (fread(&s, sizeof(s), 1, f1))
{
fwrite(&s, sizeof(s), 1, f);
}
fclose(f);
fclose(f1);
printf("Record successfully updated!\n");
}
}
This is what the update.txt file contains:
abc 123 First Last 234 33667 hi#gmail.com 101 3
You forgot the printf call, change
("Record not found! Please enter your Username and Password again.\n");
to
printf("Record not found! Please enter your Username and Password again.\n");
If you compile your program with warnings enabled you should get a warning like
t.c:68:12: warning: statement with no effect [-Wunused-value]
("Record not found! Please enter your Username and Password again.\n");
^
I'm trying to create a C program which collect's an applicant's information. When a user is prompted to enter their written subjects, the program writes rubbish data into the .csv file when they wrote one. And sometimes does the same when the number of subjects written is two.
I've tried to clear the buffer stream, but it's no use. Strangely, using different compliers like DevC++, Embarcadero DevC and VS Code produces different results.
Edit: I've also noticed the chances of the rubbish values being written into the file are lowered when the grades of the subjects is lower than the number of subjects written.
Attached below is the code. And an image of the output.
// C libraries.
#include <stdio.h> // Contains function prototypes for the standard input/output library functions, and information used by them.
#include <conio.h> // Contains function prototypes for the console input/output library functions.
#include <stdlib.h> // Contains function prototypes for conversions of numbers to text and text to numbers, memory allocation, random numbers and other utility functions.
#include <string.h> // Contains function prototypes for string-processing functions.
#include <time.h> // Contains function prototypes and types for manipulating the time and date.
#include <stdbool.h> // Contains macros defining bool, true and false, used for boolean variables.
struct Applicant
{
int applicationID;
int dateOfApplication;
char lastName[21];
char firstName[21];
char middleName[21];
char dateOfBirth[21];
int age;
char gender;
char address[100];
char phoneNumber[21];
char emailAddress[51];
char mobileNumber[21];
int numSubjectsWritten;
char csecSubjects[20][100];
char grades[20];
char programmeSelection[10];
};
struct Applicant getApplicantData()
{
struct Applicant applicant;
int i = 0;
int numSubjects;
// Asking for applicant input for various fields.
printf("| Personal |");
printf("\nEnter Last Name: ");
scanf(" %20s", &applicant.lastName);
fflush(stdin);
printf("\nEnter First Name: ");
scanf(" %20s", &applicant.firstName);
fflush(stdin);
printf("\nEnter Middle Name (If you don't have a middle name, leave this field blank.): ");
gets(applicant.middleName);
fflush(stdin);
/*
printf("\nEnter Date of Birth: ");
scanf(" %s", &applicant.dateOfBirth);
fflush(stdin);
printf("\nEnter Gender. 'M' for male, 'F' for female, (M|F): ");
scanf(" %c", &applicant.gender);
fflush(stdin);
printf("\n\n| Contact Information |");
printf("\nEnter Address: ");
gets(applicant.address);
fflush(stdin);
printf("\nEnter Phone Number: ");
gets(applicant.phoneNumber);
fflush(stdin);
printf("\nEnter Email Address: ");
gets(applicant.emailAddress);
fflush(stdin);
printf("\nEnter Mobile Number: ");
gets(applicant.mobileNumber);
fflush(stdin);
*/
printf("\n\n| Education |");
printf("\nEnter Number of Subjects Written: ");
scanf("%d", &applicant.numSubjectsWritten);
fflush(stdin);
while (i < applicant.numSubjectsWritten)
{
printf("\nEnter the subject: ");
gets(applicant.csecSubjects[i]);
fflush(stdin);
printf("\nEnter the grade for that subject: ");
scanf(" %c", &applicant.grades[i]);
fflush(stdin);
i++;
}
return applicant;
}
int main(void)
{
FILE *file = fopen("Data.csv", "a+");
int i, j;
if (!file)
{
printf("\nError! Can not open data file.\nPlease contact the Program Addmission Manager as soon as possible with the error message.");
exit(1);
}
else
{
struct Applicant applicant = getApplicantData();
//fprintf(file, "%s:%s:%s:%s:%c:%s:%s:%s:%s", applicant.lastName, applicant.firstName, applicant.middleName, applicant.dateOfBirth, applicant.gender, applicant.address, applicant.phoneNumber, applicant.emailAddress, applicant.mobileNumber);
fprintf(file, "%s:%s:%s:", applicant.lastName, applicant.firstName, applicant.middleName);
for (i = 0; applicant.csecSubjects[i][0] != '\0'; i++)
{
fprintf(file, " %s", applicant.csecSubjects[i]);
fflush(stdout);
fflush(stdin);
fflush(file);
fprintf(file, " ( %c):", applicant.grades[i]);
fflush(stdout);
fflush(stdin);
fflush(file);
}
}
return 0;
}
First problems I see:
Remove the & from all instances where you scanf a string
Don't use gets, or mix scanf and fgets
Don't fflush(stdin)
Instead of scanf, consider using a custom-made input method with condition checking and anything you need. I will give an example.
#define BUFFER_SIZE 512
void input(char* buffer){
memset(buffer, 0, BUFFER_SIZE); // Initializing the buffer.
fgets(buffer, BUFFER_SIZE, stdin);
strtok(buffer,"\n");
}
How to take input using that?
void main(){
int username[BUFFER_SIZE];
input(username);
}
A way to write a structure to a file is shown below.
void Structure_Print(Applicant* applicant, FILE* stream, int no_of_applicant){
if(no_of_applicant==0){
fprintf(stdout, "No applicant yet.\n");
return;
}
fprintf(stream, "%s:%s:%s:", applicant.lastName, applicant.firstName, applicant.middleName);
for (i = 0; applicant.csecSubjects[i][0] != '\0'; i++)
{
fprintf(stream, " %s:", applicant.csecSubjects[i]);
fprintf(stream, " %c:", applicant.grades[i]);
}
return;
}
Also, I noticed how you tried to make it readable while saving it in subject(grade) format. I recommend you to not do that. Your .csv file is just for database. Nobody is going to read it. So just store the data by comma or any character separator. It will make it easier to extract data later.
i have a structure like so:
struct profile {
char firstName[15], lastName[15];
int age, phoneNo;
};
and i've written a code to store the text data from this structure into a text file, like so:
int main()
{
FILE* fPtr;
fPtr = fopen("profile.txt", "a");
printf("\n\nPlease enter your details:");
struct profile c;
printf("\n\nEnter your first name: ");
gets(c.firstName);
printf("\nEnter your last name: ");
gets(c.lastName);
printf("\nEnter your age: ");
scanf("%d", &c.age);
printf("Enter your phone number: ");
scanf("%d", &c.phoneNo);
fprintf(fPtr, "%s#%s#%dy#%d#\n", c.firstName, c.lastName, c.age, c.phoneNo);
fclose(fPtr);
return 0;
}
the code above will store the data input into the struct into a text file of strings, each string is one profile, and each value is separated by a '#', like below:
John#Doe#35y#0123456789#
Mary Ann#Brown#20y#034352421#
Nicholas#McDonald#15y#0987654321#
i'd like to know if there's a way i can search for a certain name/age/phoneNo from the text file, select the entire string of the corresponding profile and put each value back into a structure as above so that i can display it? i've separate each value with a '#' so that the program can use the # to differentiate between each value when it reads from the file but i'm not sure how i can separate it when i read the data. should i use fgets ? i'm new to C so i'd appreciate it if someone could explain it me how.
This is not exactly what you are looking for , but it helps you start using fgets and how to search for entries(only strings now).
#include <stdio.h>
#include <string.h>
#define MYFILE "profile.txt"
#define BUFFER_SIZE 50
int main()
{
char nametoSearch[BUFFER_SIZE];
char Names[BUFFER_SIZE];
FILE* fPtr;
if (fPtr = fopen(MYFILE, "r"))
{
// flag to check whether record found or not
int fountRecord = 0;
printf("Enter name to search : ");
//use fgets if you are reading input with spaces like John Doe
fgets(nametoSearch, BUFFER_SIZE, stdin);
//remove the '\n' at the end of string
nametoSearch[strlen(nametoSearch)-1] = '\0';
while (fgets(Names, BUFFER_SIZE, fPtr))
{
// strstr returns start address of substring in case if present
if(strstr(Names,nametoSearch))
{
printf("%s\n", Names);
fountRecord = 1;
}
}
if ( !fountRecord )
printf("%s cannot be found\n",nametoSearch);
fclose(fPtr);
}
else
{
printf("file %s cannot be opened\n", MYFILE );
}
return 0;
}
My purpose is to create programme to manage records in files using c. the programme should be able to get info from console, write to a file and then read from it. Struct itself is working fine, but I'm not getting all the values i have written(see output)
and source code
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct dob
{
int date;
int month;
int year;
};
struct person
{
int id;
char firstName[20];
char lastName[20];
struct dob date;
char email[20];
int phoneNo;
}new;
void readRecordsFromFile();
void readRecordsFromKeyboard();
int main(int argc, const char * argv[]) {
puts("Hello");
while (1) {
puts("Select option. \n 1. Read records from file. \n 2. Read records from keyboard \n Type any number to exit\n");
int i;
scanf("%d", &i);
switch (i) {
case 1:
readRecordsFromFile();
break;
case 2:
readRecordsFromKeyboard();
break;
default:
return 0;
break;
}
}
return 0;
}
void readRecordsFromFile(){
//struct person new;
char filename[100];
puts("Scpecify the file name to read data");
scanf("%s", filename);
struct person *new=malloc(sizeof(struct person));
FILE * file= fopen(filename, "rb");
if (file != NULL) {
fread(new, sizeof(struct person), 1, file);
fclose(file);
}
printf("\nID: %d\nName: %s\nSurname: %s\nDay of birth:%d\nMonth of birth:%d\nYear of birth:%d\nE-mail: %s\nPhone Number: %d\n",new->id,new->firstName,new->lastName,new->date.date,new->date.month,new->date.year,new->email,new->phoneNo);
}
void readRecordsFromKeyboard(){
struct person *new=malloc(sizeof(struct person));
puts("Enter the info about person");
puts("ID number");
scanf("%d", &new->id);
puts("First Name");
scanf("%19s", new->firstName);
puts("Last name");
scanf("%19s", new->lastName);
puts("Day, month and year of birth.(by numbers, every is new line)");
scanf("%d", &new->date.date);
scanf("%d", &new->date.month);
scanf("%d", &new->date.year);
puts("Email");
scanf("%19s", new->email);
puts("Phone number");
scanf("%d", &new->phoneNo);
puts("Specify the file you want to write yor data");
char filename[100];
scanf("%99s",filename);
FILE *inputf;
inputf = fopen(filename,"wb");
if (inputf == NULL){
printf("Can not open the file.\n");
exit(0);
}else{
if (fwrite(new, sizeof(new), 1, inputf) != 1)
{
fprintf(stderr, "Failed to write to %s\n", filename);
return;
}else{
puts("Data saved\n");
printf("\nID: %d\nName: %s\nSurname: %s\nDay of birth:%d\nMonth of birth:%d\nYear of birth:%d\nE-mail: %s\nPhone Number: %d\n",new->id,new->firstName,new->lastName,new->date.date,new->date.month,new->date.year,new->email,new->phoneNo);
}
}
fclose(inputf);
}
here is your problem
inputf = fopen(filename,"wb");
This command clears file, because it file is opened with "wb".
If you are going to write multiple record in that file in several runs, open it with "wb+". Then use fseek() to go to end of file. after that write your record with fwrite().
In addition for fwrite() you need to use sizeof strusture, not pointer.Means that you need something like this:
if (fwrite(new, sizeof(struct person), 1, inputf) != 1)
{
}