#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct data {
char *first;
char *last;
char *email;
int age;
struct data *next;
};
typedef struct data dat;
dat family;
dat family_array[4];
char array[100];
void menu(){
printf("\n1. Father\n");
printf("2. Mpther\n");
printf("3. Son 1\n");
printf("4. Son 2\n");
}
int mode_select(){
int x;
printf("\nMake your choice:");
scanf("%d" ,&x);
return x;
}
Opens file and returns its address
FILE* load_read(){
FILE *fp;
fp=fopen("Family Data.dat" , "rb");
return fp;
}
FILE* write(){
FILE *fp;
fp=fopen("Family Data.dat" , "wb");
return fp;
}
Reads data for struct
dat new_data( const char *first , const char *last , const char *email , int age){
printf("\nGive first name: ");
scanf("%s" , array );
first=(char*)malloc((strlen(array)+1)*sizeof(char));
strcpy( &(family.first), array);
printf("\nGive last name: ");
scanf("%s" , array);
last=(char*)malloc((strlen(array)+1)*sizeof(char));
strcpy(&(family.last), array);
printf("\nGive email address: ");
scanf("%s" , array);
email=(char*)malloc((strlen(array)+1)*sizeof(char));
strcpy(&(family.email) , array);
printf("\nGive age: ");
scanf("%d" , &(family.age));
return family;
}
Saves data from struct to file
void save_to_file(FILE *fp , dat x){
fprintf(fp , "Dataaa:\n ");
fprintf(fp ,"Name: %s %s\n" , x.first , x.last);
fprintf(fp , "Email: %s\n" , x.email);
fprintf(fp , "Age: %d\n" , x.age);
}
Saves data to an array
void save(x){
family_array[x-1]=new_data(family.first , family.last , family.email , family.age);
}
Main fuction
int main(){
int x ,i;
FILE *fp;
for(i=0;i<4;i++){
mode();
x=mode_select();
fp=write();
save(x);
save_to_file(fp , family_array[i]);
}
fclose(fp);
return 0;
}
The programm crashes when its time to save data to file with save_to_file fuction!
Thank you very much for your help!
Your family.first, family.last and family.email pointer are never initialized, but you write to them using strcpy in new_data
It's not clear what you are trying to do with the arguments of new_data, and why you never use their value but replace it by a newly allocated buffer, which you never write to and never free
The new_data function is an unreadable mess, as well as being wrong. It already returns all the information that it reads via its return value, so it does not need any parameters.
The right way is:
dat new_data(void)
{
dat item = { 0 };
char array[100]; // does not need to be global
printf("Give first name: ");
if ( 1 != scanf("%99s", array ) )
exit(EXIT_FAILURE);
item.first = malloc( strlen(array) + 1 );
strcpy(item.first, array);
// same for other items....
return item;
}
and the code in save would be:
family_array[x-1] = new_data();
Your object family is not required either.
If you want to make new_data() be able to recover from errors by doing something other than exit then you will need to return a success/failure indication. (and include extra code for freeing memory).
Note that the POSIX functions strdup and/or getline would make this code a bit simpler.
Related
I'm basically trying to add a book into my libraryy.txt file my problem is the compiler says that there's too few arguments to perform the addBook() function, what should I include in the addBook() function parentheses in my main function?
struct book{
char *title;
char *author;
char *subject;
};
struct library {
struct book collection;
int num_books;
struct library *next;
};
This is my addBook() function:
void addBook(struct library* thislib){
FILE *cfPtr;
cfPtr = fopen("libraryy.txt", "a");
char strtitle[MAX];
char strauthor[MAX];
char strsubject[MAX];
int operation;
struct library acollection;
printf("Title: ");
scanf("%s", strtitle);
printf("Author: ");
scanf("%s", strauthor);
printf("Subject: ");
scanf("%s", strsubject);
thislib->collection.title = strtitle;
thislib->collection.author = strauthor;
thislib->collection.subject = strsubject;
printf("The book %s author %s subject %s has been added to the library.\n", thislib->collection.title, thislib->collection.author, thislib->collection.subject);
fprintf(cfPtr, "%d %s %s %s\n", operation, collection.title, collection.author, collection.subject);
}
The compiler is telling me that there are too few arguments to perform function addBook..what should I add in the parentheses for addBook?? The error is in my main method below:
FILE *cfPtr;
int operation;
if ((cfPtr = fopen("libraryy.txt","a")) == NULL){
printf("File could not be opened...\n");
}
else {
while(1){
operate();
printf("Enter an operation: ");
scanf("%d", &operation);
switch(operation){
case 1:
addBook(); //it basically gave me the error here which is 'too few arguments to perform function addBook'
break;
Don't get me wrong, I know what does too few arguments/no arguments mean but what should I include in those parentheses as arguments? :") Need some help.
The code is supposed to Accept Data,Display the entire data stored till the current execution,Modify or make changes to the already accepted data.
WHAT IM LOOKING FOR IN AN ANSWER:how to write the code for a Modify module?
how to correct the Add or accept data,Display
data so they function perfectly.
#include<stdio.h>
typedef struct
{
int select;
char lastname[25];
char firstname[25];
char address[25];
int phonenumber[25];
} addressbook;
#define ARRAYLEN 2 //The lecturer told to use this "#define ARRAYLEN 2
addressbook a[ARRAYLEN]; //but why 2?and why use ARRAYLEN 2 with define
FILE *fp;
int main() //how is it affecting my program
{
int i;
int c;
int fgetc(FILE *stream);
int fputc(int c,FILE *stream);
fp = fopen("addressbook.dat","a+");
//ADD
for( i=0; i<ARRAYLEN ; ++i)
{
printf("enter details\n");
printf("enter lastname:\n");
scanf("%s", a[i].lastname);
printf("enter firstname:\n");
scanf("%s", a[i].firstname);
printf("enter address:\n");
scanf("%s", a[i].address);
printf("enter phone number:\n");
scanf("%d", a[i].phonenumber);
fwrite(&a[i], sizeof(a), 1, fp); /* notice, array indexed */
};
fclose(fp);
//DISPLAY
fopen("addressbook.dat", "r");
for(i=0; i<ARRAYLEN; ++i)
{
fread(&a[i], sizeof(a), 1, fp );
fgetc;
printf("first name is %s",a[i].firstname);
printf("last name is %s",a[i].lastname);
printf("the address is %s",a[i].address);
printf("the phonenumber is %d",a[i].phonenumber);
};
fclose(fp);
return 0;
}
IMPORTANT NOTE: I use a windows vista os and the compiler is Turbo C++
#include<stdio.h>
#include<conio.h>
#include<stdlib.h>
#include<string.h>
struct student{
char *name;
char *addr;
int age;
int clas;
}*stu;
int main()
{
FILE *fp;
int choice,another;
size_t recsize;
size_t length;
struct student *stu=(struct student *)malloc(sizeof(struct student));
stu->name=(char *) malloc(sizeof(char)*20);
stu->addr=(char*)malloc(sizeof(char)*20);
recsize=sizeof(*stu);
fp=fopen("student.txt","a+");
if(fp==NULL)
{
fp=fopen("student.txt","w+");
if(fp==NULL)
{
printf("cannot open the file");
exit(1);
}
}
do
{
fseek(fp,1,SEEK_END);
printf("Please Enter student Details\n");
printf("Student Name: ");
scanf("%s",stu->name);
printf("Address: ");
scanf("%s",stu->addr);
printf("Class: ");
scanf("%s",&stu->clas);
printf("Age: ");
scanf("%s",&stu->age);
fwrite(stu,recsize,1,fp);
printf("Add another Enter 1 ?\n");
scanf("%d",&another);
}while(another==1);
fclose(fp);
free(stu);
}
I have code in C which has a structure Student. I am trying to get all structure members values from user. Memory is allocated for structure and two members *name and *addr. when I try to write those values using fwrite() function in a file Student.txt it shows random output ( ཀའ㌱䔀8䵁ཀའ㈱䔀1䵁 ) like this in a file and it is not in readable form. Please provide me the best way to write members of structure in file using fwrite() function.
You need to use %d instead of %s for ints
printf("Class: ");
scanf("%s",&stu->clas);
printf("Age: ");
scanf("%s",&stu->age);
should be
printf("Class: ");
scanf("%d",&stu->clas);
printf("Age: ");
scanf("%d",&stu->age);
And as pointed out by #David Hoelzer in comments: you're writing the value of the pointers rather than what they contain, change
struct student{
char *name;
char *addr;
to
struct student{
char name[20];
char addr[20];
and delete those lines:
stu->name=(char *) malloc(sizeof(char)*20);
stu->addr=(char*) malloc(sizeof(char)*20);
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)
{
}
How can I pass values to struct variable I'm trying to get the employee information from the user then write them in a file, but I got a segmentation fault after entering employee name.
This is my code.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct record_em{
int id;
char name[20];
int salary;
int age;
};
int main( void )
{
struct record_em employee;
FILE *fp;
int id, salary, age;
char name[20];
int n=1;
fp = fopen("empRecord.dat","a");
while(n==1){
printf("\nEnter Employee ID\n");
scanf("%d",&id);
employee.id=id;
printf("\nEnter Employee Name\n");
scanf("%s",name);
employee.name=name;
printf("\nEnter Employee Salary\n");
scanf("%d",&salary);
employee.salary=salary;
printf("\nEnter Employee Age\n");
scanf("%d",&age);
employee.age=age;
fwrite(&employee,sizeof(employee),1,fp);
printf("Enter 1 to add new record \n");
scanf("%d",&n);
}
fclose(fp);
return 0;
}
Output (taken from comment):
Fatmahs-MacBook-Air:~ fatmah$ gcc -o em em.c
Fatmahs-MacBook-Air:~ fatmah$ ./em
Enter Employee ID
88
Enter Employee Name
uu
Segmentation fault: 11
Change
scanf("%s",name);
employee.name=name;
to
scanf("%s",name);
strcpy(employee.name, name);
Of, better still, as suggested by Dukeling & hmjd
scanf("%19s", employee.name);
Here is one major problem:
scanf("%s",name);
employee.name=name;
The member name is an array, you can't assign to it. Instead use strcpy to copy to it.
Create a typedef struct record_tto make the things shorter and easier to understand.
typedef struct {
int id;
char name[20];
int salary;
int age;
} record_t;
Create the file and format it first.
void file2Creator( FILE *fp )
{
int i; // Counter to create the file.
record_t data = { 0, "", 0, 0 }; // A blank example to format the file.
/* You will create 100 consecutive records*/
for( i = 1; i <= 100; i++ ){
fwrite( &data, sizeof( record_t ), 1, fp );
}
fclose( fp ); // You can close the file here or later however you need.
}
Write the function to fill the file.
void fillFile( FILE *fp )
{
int position;
record_t data = { 0, "", 0, 0 };
printf( "Enter the position to fill (1-100) 0 to finish:\n?" );
scanf( "%d", &position );
while( position != 0 ){
printf( "Enter the id, name, and the two other values (integers):\n?" );
fscanf( stdin, "%d%s%d%d", &data.id, data.name, data.salary, data.age );
/* You have to seek the pointer. */
fseek( fp, ( position - 1 ) * sizeof( record_t ), SEEK_SET );
fwrite( &data, sizeof( record_t ), 1, fp );
printf( "Enter a new position (1-100) 0 to finish:\n?" );
scanf( "%d", &position );
}
fclose( fPtr ); //You can close the file or not, depends in what you need.
}
You can use this as reference Comparing and checking columns in two files