0

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;

Bibash Adhikari
  • 292
  • 4
  • 16
  • 2
    [don't cast malloc](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc) – Barmar Mar 27 '15 at 02:38
  • BTW you could use calloc(1, sizeof(collection)) and avoid the ugly setting of all struct elements to NULL. – jarmod Mar 27 '15 at 02:43
  • Your use of realloc() is also wrong. The first parameter needs to be a pointer to something that you're going to reallocate & resize. In your case it's always passed in as NULL because you never allocated any memory to fname, lname etc. Why don't you just use strdup() instead of realloc/strcpy? – jarmod Mar 27 '15 at 02:51
  • Are you sure this is C and not C++? – user253751 Mar 27 '15 at 03:13

4 Answers4

2

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.

  • And it is deprecated because the inability to limit the number of characters poses a highly exploited security vulnerability – clearlight Mar 27 '15 at 02:43
  • i used gets because i dont know how long a name can be.So i thought i would get input using gets and then again copy in fname allocating the memory. – Bibash Adhikari Mar 28 '15 at 06:16
  • Thats not the way define a macro for the max size –  Apr 02 '15 at 17:05
1

Try sizeof (struct collection) without the *

Iharob Al Asimi
  • 52,653
  • 6
  • 59
  • 97
clearlight
  • 12,255
  • 11
  • 57
  • 75
  • it works but it does not write the given data in file all i get in file is like this `g¨ ˆ¨ Ho¨ pg¨ €g¨ gM ˆM HoM pgM €gM ` – Bibash Adhikari Mar 28 '15 at 06:36
1

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.

Barmar
  • 741,623
  • 53
  • 500
  • 612
0


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 getchar
Finally 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
enter image description here

prasad
  • 1,277
  • 2
  • 16
  • 39
  • first of all "w+" is not append mode .i tried with "a+" (append mode)with only one file descriptor it's working fine. – prasad Mar 29 '15 at 09:14
  • Hi i am not sure about devc++,[this is my code](http://pastebin.com/sWFegLRP) with "a+" and it contains out put also. – prasad Mar 29 '15 at 14:10