i'm trying to apply malloc in my code, but still having a problem, there's an error saying : "request for member 'id' in something not a structure or union".
what i want to do is to use malloc instead of array.. and store the structure in each indices, i tried array[i]->id, but bunch of garbage character stored on my text file. I also increment i and didn't use loop, coz user may only input once... this is my code:
#include<stdio.h>
#include<stdlib.h>
struct studentinfo{
char id[8];
char name[30];
char course[5];
}s1;
main(){
int i=0;
FILE *stream = NULL;
stream = fopen("studentinfo.txt", "a+");
struct studentinfo *array[50];
array[i] = (struct studentinfo*) malloc(sizeof(struct studentinfo));
printf("Enter Student ID: ");
scanf("%s", array[i].id);
fflush(stdin);
printf("Enter Student Name: ");
gets(array[i].name);
fflush(stdin);
printf("Enter Student Course: ");
scanf("%s", array[i].course);
fprintf(stream, "\n%s,\t%s,\t%s", array[i].id, array[i].name, array[i].course);
i++;
fclose(stream);
free(array);
getch();
}
hope you can help me... thanks in advance :)
You're accessing the properties incorrectly.
array[i]
is a pointer to a struct, so
array[i].id
is going to give you an error. Use
array[i]->id
to dereference.
You should initialize the array and free it like this: Am i using malloc properly?
Also... follow Zurahn's instruction.
Related
struct Book {
char *title;
char *authors;
unsigned int year;
unsigned int copies;
};
void book_to_add()
{
struct Book book;
struct Book *ptrbook = (struct Book*) malloc(sizeof(struct Book));
printf("Book you would like to add: \n");
scanf("%[^\n]", book.title);
printf("Author of Book: \n");
scanf("%[^\n]", book.authors);
printf("Year book was published: \n");
scanf("%u", &book.year);
printf("number of copies: \n ");
scanf("%u", &book.copies);
add_book(book);
free(ptrbook);
}
I am quite new to programming and I am unsure what I should do to solve this, I know it might have to do with the pointer elements in the struct.
title and authors are uninitialized pointers, you will need to allocate memory for them (i.e. make them point to some valid memory location) if you want to store anything there, e.g.:
book.authors = malloc(100);
book.authors = malloc(100);
for a buffer able to store 99 character + the null terminator '\0'.
On that note, make sure to use a size delimiter in scanf otherwise there is the chance for buffer overflow, e.g:
scanf(" %99[^\n]", book.title);
scanf(" %99[^\n]", book.authors);
for a buffer of 100 characters.
#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);
I was working on my college project in C and got some problem.
I used pointer to structure and used it to write in a file using fwrite but it isn't helping.Here is the code I used.
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
#include<conio.h>
struct collection{
char *fname, *lname, *telephone, *address, *seat;
};
collection * alloc( ){
struct collection *r = (struct collection *) malloc (sizeof(collection*));
r->fname = NULL;
r->lname = NULL;
r->telephone = NULL;
r->address = NULL;
r->seat = NULL;
return (r);
}
void string_realloc_and_copy (char **dest, const char *src){
*dest =(char *) realloc (*dest, strlen (src) + 1);
strcpy (*dest, src);
}
int main(){
char ch = 'Y', temp[50];
FILE *ptf;
struct collection *asd;
asd = alloc();
//printf("%d",sizeof(asd));
//opening file
ptf = fopen("lang.txt","w+");
do{
printf("First name: ");
gets(temp);
string_realloc_and_copy(&asd->fname,temp);
printf("Last name: ");
gets(temp);
string_realloc_and_copy(&asd->lname,temp);
printf("Telephone: ");
gets(temp);
string_realloc_and_copy(&asd->telephone,temp);
printf("Address: ");
gets(temp);
string_realloc_and_copy(&asd->address,temp);
printf("Seat you want to book: ");
gets(temp);
string_realloc_and_copy(&asd->seat,temp);
fwrite(asd,12*sizeof(collection),1,ptf);
fflush(ptf);
//fprintf(ptf,"\n");
printf("Do you wish to enter another data...? (Y/N) ");
ch = getch();
}while((ch=toupper(ch))== 'Y');
rewind(ptf);
while(fread(asd,12*sizeof(collection),1,ptf) == 1){
printf("\n\n%s",asd->fname);
printf("\n\n%s",asd->lname);
printf("\n\n%s",asd->telephone);
printf("\n\n%s",asd->address);
printf("\n\n%s",asd->seat);
}
fclose(ptf);
}
It works until asd->telephone is reached it ask for address and goes unresponding. I could not figure out what i did wrong. I thought it was out of memory so i change
struct collection *r = (struct collection *) malloc (sizeof(collection*));
to
struct collection *r = (struct collection *) malloc (12*sizeof(collection*));
And it worked for some time and again same thing happened. I am using devC++ for compilation. Thanks in advance;
First you should not use gets() because its deprecated and there is no limit in how many characters it gets from stdin. I recommand you to use fgets. You should use malloc like this for a pointer
malloc(sizeof(*collection));
This way you allocate memory for a pointer.
And one another thing try this program with putc() and see if it works.
malloc (sizeof(collection*)) should be malloc(sizeof(*collection)). Your code is only allocating enough space for a pointer to the collection type, not the size of the structure that the collection pointer points to.
This also shows why it's a bad idea to use the same name for both a variable and a type. If you'd used different names, you would have gotten an error from the compiler. Use collection_t for the type.
Try sizeof (struct collection) without the *
i found so many changes in your code.First change is struct collection instead of collection .Second change is i used two file descriptors one for reading another one for writing.Third in your code you are initializing "asd" only once due to this it will write same structure every time into file . So i initialized inside do-while loop.Fourth one i used scanf instead of gets because when you are taking multiple inputs it's skipping some inputs.Fifth i removed 12 form fwrite and fread.Sixth i used one more getchar because we will press enter after giving seat number so ch is taking that enter to take the user input i had to use one more getcharFinally the changed code is
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<string.h>
//#include<conio.h>
struct collection
{
char *fname, *lname, *telephone, *address, *seat;
};
struct collection *alloc( ){
struct collection *r= malloc(sizeof(struct collection));
r->fname = NULL;
r->lname = NULL;
r->telephone = NULL;
r->address = NULL;
r->seat = NULL;
return (r);
}
void string_realloc_and_copy (char **dest, const char *src){
*dest =(char *) realloc (*dest, strlen (src) + 1);
strcpy (*dest, src);
}
int main(){
char ch = 'Y', temp[50];
FILE *ptf;
struct collection *asd;
//printf("%d",sizeof(asd));
//opening file
ptf = fopen("lang.txt","wb");
do{
asd = alloc();
printf("First name: ");
scanf("%s",temp);
string_realloc_and_copy(&asd->fname,temp);
printf("Last name: ");
scanf("%s",temp);
string_realloc_and_copy(&asd->lname,temp);
printf("Telephone: ");
scanf("%s",temp);
string_realloc_and_copy(&asd->telephone,temp);
printf("Address: ");
scanf("%s",temp);
string_realloc_and_copy(&asd->address,temp);
printf("Seat you want to book: ");
scanf("%s",temp);
string_realloc_and_copy(&asd->seat,temp);
fwrite(asd,sizeof(struct collection),1,ptf);
fflush(ptf);
//fprintf(ptf,"\n");
printf("Do you wish to enter another data...? (Y/N) ");
ch = getchar();
ch = getchar();
}while((ch=toupper(ch))== 'Y');
//rewind(ptf);
fclose(ptf);
FILE *ptf1;
ptf1 = fopen("lang.txt","rb");
while(fread(asd,sizeof(struct collection),1,ptf1)){
printf("\n\n%s",asd->fname);
printf("\n\n%s",asd->lname);
printf("\n\n%s",asd->telephone);
printf("\n\n%s",asd->address);
printf("\n\n%s",asd->seat);
}
fclose(ptf1);
}
and sample out put is
This question already has an answer here:
free char*: invalid next size (fast) [duplicate]
(1 answer)
Closed 8 years ago.
I have a program and gets information from the keyboard and puts them into a struct and then write the struct to a file.
However, when I'm reallocating memory for the second time it seems to fail for no reason. Also, if I enter more than 1 person's information, the program fails in the end with a seg fault. The program runs fine if I enter just 1 person's information.
Thanks.
// Program
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
typedef struct person person;
struct person {
char fname[20];
char lname[20];
int num;
};
int main(void){
int size = 0;
int count = 0;
person* listofperson = NULL;
char answer = 'n';
FILE* myfile;
do{
char* buf = (char*)malloc(sizeof(char)*50);
printf("Please enter the person's first name: \n");
fgets(buf, 50, stdin);
if(count == size){
size += 2;
listofperson = (person*)realloc(listofperson, (size_t)(sizeof(person)*size));
}
strncpy((listofperson+count)->fname, buf, 50);
printf("Please enter the person's last name: \n");
fgets(buf, 50, stdin);
strncpy((listofperson+count)->lname, buf, 50);
printf("Please enter the person's number: \n");
fgets(buf, 50, stdin);
sscanf(buf, "%d", &((listofperson+count)->num));
free(buf);
count++;
printf("Do you want to enter another one?\n");
answer = getchar();
getchar();
}while(tolower(answer) != 'n');
myfile = fopen("myfile", "a");
for(int i = 0; i < count; i++){
fprintf(myfile, "%s", (listofperson+i)->fname );
fprintf(myfile, "%s", (listofperson+i)->lname );
fprintf(myfile, "%d\n", (listofperson+i)->num );
}
fclose(myfile);
myfile = NULL;
free(listofperson);
}
For one thing, the people who are saying that realloc() doesn't work with a NULL pointer aren't speaking the truth. The behavior is documented here for C++ and here for C, it just works like malloc() in the case of a NULL pointer passed. Although I would agree that it is bad practice to assign memory that way.
You are not checking for errors in your malloc() and realloc() calls, they are not guaranteed to succeed, so you shouldn't assume they will.
In this case you shouldn't name your point to a person node "list of people", as this convention may be confused with a linked list. I would strongly reccomend you attempt to implement a linked lists for this programming case, since that is basically how you are working with your data anyways. For a tutorial on linked lists, see this link.
You should change the name of the file in fopen() to include a .txt extension. Otherwise the system will not know what the file type is.
change
struct person {
char fname[20];
char lname[20];
int num;
};
to
struct person {
char fname[50];
char lname[50];
int num;
};
Which is too small, it's already pointed out by ouah. It is necessary to align the value of one.
The error message indicates that the memory is destroyed beyond the area secured.
This is a homework question. My compiler is CodeBlocks.
Here is my code :
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Address{
char number[5];
char street[30];
char city[30];
};
struct Employee{
char ID[7];
char name[31];
struct Address *addr;
};
int main(){
int n,i;
char temp[7];
printf("Enter number of Employee : ");
scanf("%d",&n);
struct Employee **p=(struct Employee **)malloc(n*sizeof(struct Employee *));
for (i=0; i<n; i++)
{
p[i]=(struct Employee *)malloc(sizeof(struct Employee));
p[i]->addr=(struct Address *)malloc(sizeof(struct Address));
}
for(i=0; i<n; i++)
{
printf("Employee #%d\n",i+1);
printf("Enter ID : ");
gets(p[i]->ID);
printf("Enter Name : ");
gets(p[i]->name);
printf("Enter Home number : ");
gets(p[i]->addr->number);
printf("Enter Street : ");
gets(p[i]->addr->street);
printf("Enter City : ");
gets(p[i]->addr->city);
}
}
My problem is that when I run this code, I cannot enter the ID for the #1 employee; however, I can enter in the ID for employee #2 and #3.
Where is my problem?
There seems to be some issue with gets() reading something from the console before the first pass of the loop.
Adding gets(temp); right before the loop seems to fix it. A better solution would be to use something other than gets().
The initial scanf("%d", &n); doesn't consume the trailing newline, so it's left available for the gets() call.
Incidentally, never use gets(). It cannot be used safely. For example, if you're reading into a 6-byte array, and the user enters 10 characters, you have a buffer overflow. Consider using fgets() instead (but note that, unlike gets(), it leaves the '\n' character in the buffer).
You should ever explicit clear the input buffer after any user-input. And you should make your inputs safe with size limiter. And you should use the return value from scanf.
scanf("%d",&n);while(getchar()!='\n');
...
scanf("%6[^\n]",p[i]->ID);while(getchar()!='\n');
...
scanf("%30[^\n]",p[i]->name);while(getchar()!='\n');
...
scanf("%4[^\n]",p[i]->addr->number);while(getchar()!='\n');
...
scanf("%29[^\n]",p[i]->addr->street);while(getchar()!='\n');
...
scanf("%29[^\n]",p[i]->addr->city);while(getchar()!='\n');