Problem in writing structure to Binary file in C lang

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • zehra.mb@gmail.com

    Problem in writing structure to Binary file in C lang

    Hi,
    I had written application for storing employee data in binary file and
    reading those data from binary file and display it in C language.
    But I face some issue with writing data to binary file.
    Here is my part of my code.

    struct cust_data
    {
    int nCAFID;
    char *szFirstName;
    };

    typedef struct cust_data CUST_DATA;
    CUST_DATA *pCustdata = NULL;
    int AddRecord()
    {
    FILE *fp;
    fp = fopen("Input.da t","ab+");
    return fp;
    pCustdata = malloc(sizeof(C UST_DATA));

    pCustData->szFirstName = malloc(sizeof(p CustData-
    >szFirstName) );
    printf("Enter CAFID : ");
    scanf("%d",&pCu stData->nCAFID);

    printf("Enter First Name : ");
    scanf("%s",pCus tData->szFirstName) ;

    fwrite(pCustDat a,sizeof(CUST_D ATA),1,fp);

    fclose(fp);

    free(pCustData->szFirstName) ;
    free(pCustData)
    }

    now here when i write a structure to file, it writes nCAFID and
    inplace of szFirstName it writes pointer to string.
    But i need to write string..
    if i take szFirstName as char array then it is wroking fine.....but i
    want to use heap memory instead of stack..
    can anyone help me............. .....??
    thanks in advance........ .....


  • Richard Heathfield

    #2
    Re: Problem in writing structure to Binary file in C lang

    zehra.mb@gmail. com said:
    Hi,
    I had written application for storing employee data in binary file and
    reading those data from binary file and display it in C language.
    But I face some issue with writing data to binary file.
    Here is my part of my code.
    >
    struct cust_data
    {
    int nCAFID;
    char *szFirstName;
    };
    >
    typedef struct cust_data CUST_DATA;
    CUST_DATA *pCustdata = NULL;
    int AddRecord()
    {
    FILE *fp;
    fp = fopen("Input.da t","ab+");
    What if it fails?
    return fp;
    Oops - fp is not an int. (I suspect this is simply accidental or forgotten
    code.)
    pCustdata = malloc(sizeof(C UST_DATA));
    What if it fails?
    >
    pCustData->szFirstName = malloc(sizeof(p CustData-
    >>szFirstName)) ;
    This will allocate enough bytes to store a pointer, which isn't what you
    want. Decide how many bytes to allocate for storing a first name and
    allocate that many, or simply make szFirstName an array of char and drop
    the szFirstName malloc completely.
    printf("Enter CAFID : ");
    scanf("%d",&pCu stData->nCAFID);
    >
    printf("Enter First Name : ");
    scanf("%s",pCus tData->szFirstName) ;
    You run the risk of having your user enter (accidentally or maliciously)
    more characters than you can store, resulting in a buffer overrun.
    >
    fwrite(pCustDat a,sizeof(CUST_D ATA),1,fp);
    This won't work if you dynamically allocate szFirstName - you'd have to
    write it separately and make a note of the size so that you can read it
    back in. Making szFirstName an ordinary array will fix this.


    --
    Richard Heathfield <http://www.cpax.org.uk >
    Email: -http://www. +rjh@
    Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
    "Usenet is a strange place" - dmr 29 July 1999

    Comment

    • Jens Thoms Toerring

      #3
      Re: Problem in writing structure to Binary file in C lang

      zehra.mb@gmail. com wrote:
      I had written application for storing employee data in binary file and
      reading those data from binary file and display it in C language.
      But I face some issue with writing data to binary file.
      That's usually not a good idea since then you probably won't be
      able to read in that file on a machine with a different archi-
      tecture and maybe even when you compile the program with a dif-
      ferent compiler (or compiler version or options) on the same
      machine! Moreover, you run into problems if the struture contains
      pointers, as you already found out.
      Here is my part of my code.
      struct cust_data
      {
      int nCAFID;
      char *szFirstName;
      };
      typedef struct cust_data CUST_DATA;
      CUST_DATA *pCustdata = NULL;
      int AddRecord()
      {
      FILE *fp;
      fp = fopen("Input.da t","ab+");
      return fp;
      pCustdata = malloc(sizeof(C UST_DATA));
      pCustData->szFirstName = malloc(sizeof(p CustData->szFirstName) );
      Here you already have a problem. You allocate just enough memory
      to store a pointer, but rather likely not enough memory to store
      a string (unless it's a very short one).
      printf("Enter CAFID : ");
      scanf("%d",&pCu stData->nCAFID);
      printf("Enter First Name : ");
      scanf("%s",pCus tData->szFirstName) ;
      And if the string the user entered is longer that the size of a
      pointer to a string then you write over memory yiu don't own.
      If you're lucky you will get an immediate segmentation fault
      bur if you're unlucky the program will look as if it's working
      and crash in some seemingly unrelated place.

      Just some hint: using scanf() this way is inherently unsafe.
      This way the user can always enter a string that's longer
      than you allocated. If you use scanf() then you will have
      to specify a maximum length of the string to be read in to
      avoid that (just put the number between the '%' and the 's'
      or put a '*' in between and make the maximum number of
      characters the next argument of scanf()).
      fwrite(pCustDat a,sizeof(CUST_D ATA),1,fp);
      fclose(fp);
      free(pCustData->szFirstName) ;
      free(pCustData)
      }
      now here when i write a structure to file, it writes nCAFID and
      inplace of szFirstName it writes pointer to string.
      But i need to write string..
      if i take szFirstName as char array then it is wroking fine.....but i
      want to use heap memory instead of stack..
      It's not something related to "stack" or "heap" memory. The
      problem is that you write just a pointer to the file. And that
      pointer value only makes sense while the program that writes
      out the structure is still running and hasn't deallocated the
      memory the pointer points to. Once the memory has been de-
      allocated or when you try to read in the structure with a
      new instance of the program (or a different one) the pointer
      points to some memory location where there are just random
      data (or may even point to memory you're not allowed to
      access).

      Trying to store a pointer to something instead of the real
      thing is like putting a foto of your birthday cake into the
      fridge and throwing the cake away. While that may safe some
      room in the fridge don't be surprised if the foto doen't
      taste as well as the real cake;-)

      Actually, if it would be possible to just store pointers
      and still get back what they were pointing to you wouldn't
      have to store the structure but you could instead just store
      the pointer to the structure itself.

      So the only reasonable way to write out a structure to a file
      is to "serialize" its data. Instead of simply writing out the
      structure to a binary file write it's contents in e.g. ASCII,
      i.e. first a line with the 'nCAFID' number, then another one
      with the string. Only that will allow you to get back the data
      in all possible circumstances.

      Regards, Jens
      --
      \ Jens Thoms Toerring ___ jt@toerring.de
      \______________ ____________ http://toerring.de

      Comment

      • zehra.mb@gmail.com

        #4
        Re: Problem in writing structure to Binary file in C lang

        On Apr 18, 3:22 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:

        Thaks a lot for the reply..
        zehra...@gmail. com said:
        >
        >
        >
        Hi,
        I had written application for storing employee data inbinaryfileand
        reading those data frombinaryfilea nd display it inClanguage.
        But I face some issue withwritingdata tobinaryfile.
        Here is my part of my code.
        >
        struct cust_data
        {
        int nCAFID;
        char *szFirstName;
        };
        >
        typedef struct cust_data CUST_DATA;
        CUST_DATA *pCustdata = NULL;
        int AddRecord()
        {
        FILE*fp;
        fp = fopen("Input.da t","ab+");
        >
        What if it fails?
        >
        return fp;
        >
        Oops - fp is not an int. (I suspect this is simply accidental or forgotten
        code.)
        >
        sorry thats my mistake..my code is like
        if(!fp)
        return 0;
        pCustdata = malloc(sizeof(C UST_DATA));
        >
        What if it fails?
        >
        >
        >
        pCustData->szFirstName = malloc(sizeof(p CustData-
        >szFirstName) );
        >
        This will allocate enough bytes to store a pointer, which isn't what you
        want. Decide how many bytes to allocate for storing a first name and
        allocate that many, or simply make szFirstName an array of char and drop
        the szFirstName malloc completely.
        >
        printf("Enter CAFID : ");
        scanf("%d",&pCu stData->nCAFID);
        >
        printf("Enter First Name : ");
        scanf("%s",pCus tData->szFirstName) ;
        >
        You run the risk of having your user enter (accidentally or maliciously)
        more characters than you can store, resulting in a buffer overrun.
        >
        >
        >
        fwrite(pCustDat a,sizeof(CUST_D ATA),1,fp);
        >
        This won't work if you dynamically allocate szFirstName - you'd have to
        write it separately and make a note of the size so that you can read it
        back in. Making szFirstName an ordinary array will fix this.
        ya thats true.
        As i mentioned it works fine if i take simple array of characters..
        I found what is the problem.Here i am writing pointer to strig in file
        and after using the structure i am deaalocation memory for it.
        so next time when it reads from a file and try to get value at that
        pointer,it wont get the actual data.
        so may be i need to serialize the data.

        Regards,
        Zehra
        --
        Richard Heathfield <http://www.cpax.org.uk >
        Email: -http://www. +rjh@
        Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
        "Usenet is a strange place" - dmr 29 July 1999

        Comment

        • zehra.mb@gmail.com

          #5
          Re: Problem in writing structure to Binary file in C lang

          On Apr 21, 9:26 am, zehra...@gmail. com wrote:
          On Apr 18, 3:22 pm, Richard Heathfield <r...@see.sig.i nvalidwrote:
          >
          Thaks a lot for the reply..
          >
          >
          >
          zehra...@gmail. com said:
          >
          Hi,
          I had written application for storing employeedatainb inaryfileand
          reading thosedatafrombi naryfileand display it inClanguage.
          But I face some issue withwritingdata tobinaryfile.
          Here is my part of my code.
          >
          struct cust_data
          {
          int nCAFID;
          char *szFirstName;
          };
          >
          typedef struct cust_data CUST_DATA;
          CUST_DATA *pCustdata = NULL;
          int AddRecord()
          {
          FILE*fp;
          fp = fopen("Input.da t","ab+");
          >
          What if it fails?
          >
          return fp;
          >
          Oops - fp is not an int. (I suspect this is simply accidental or forgotten
          code.)
          >
          sorry thats my mistake..my code is like
          if(!fp)
          return 0;
          >
          >
          >
          pCustdata = malloc(sizeof(C UST_DATA));
          >
          What if it fails?
          >
          pCustData->szFirstName = malloc(sizeof(p CustData-
          >>szFirstName)) ;
          >
          This will allocate enough bytes to store a pointer, which isn't what you
          want. Decide how many bytes to allocate for storing a first name and
          allocate that many, or simply make szFirstName an array of char and drop
          the szFirstName malloc completely.
          >
          printf("Enter CAFID : ");
          scanf("%d",&pCu stData->nCAFID);
          >
          printf("Enter First Name : ");
          scanf("%s",pCus tData->szFirstName) ;
          >
          You run the risk of having your user enter (accidentally or maliciously)
          more characters than you can store, resulting in a buffer overrun.
          >
          fwrite(pCustDat a,sizeof(CUST_D ATA),1,fp);
          >
          This won't work if you dynamically allocate szFirstName - you'd have to
          write it separately and make a note of the size so that you can read it
          back in. Making szFirstName an ordinary array will fix this.
          >
          ya thats true.
          As i mentioned it works fine if i take simple array of characters..
          I found what is the problem.Here i am writing pointer to strig in file
          and after using the structure i am deaalocation memory for it.
          so next time when it reads from a file and try to get value at that
          pointer,it wont get the actualdata.
          so may be i need toserializethed ata.
          >
          Regards,
          Zehra
          >
          --
          Richard Heathfield <http://www.cpax.org.uk >
          Email: -http://www. +rjh@
          Google users: <http://www.cpax.org.uk/prg/writings/googly.php>
          "Usenet is a strange place" - dmr 29 July 1999
          Hi Jens,
          Thanks for the reply.
          you are right.
          Can you please tell me how would i serialize data in C(can you please
          provide example code)?
          Also for scanf now i have written

          printf("Enter First Name : ");
          scanf("%50s",pC ustData->pszFirstName );
          printf("Enter Last Name : ");
          scanf("%50s",pC ustData->pszLastName) ;

          i want the name should not acceed 50 char,but here in this case if i
          give 52 chars for fisrt name as input it will take 50 for first name
          and rest 2 for last name.
          it doesnt allow me to enter last name.
          So what i sould do to get only 50 chars and discard rest 2 chars?

          Thanks & Regards,
          Zehra

          Comment

          • santosh

            #6
            Re: Problem in writing structure to Binary file in C lang

            zehra.mb@gmail. com wrote:

            Can you please tell me how would i serialize data in C(can you please
            provide example code)?
            It's usually better to use existing code than to reinvent the wheel.

            <http://tpl.sourceforge .net/>
            <http://en.wikipedia.or g/wiki/Serialization -- A general overview
            Also for scanf now i have written
            >
            printf("Enter First Name : ");
            To ensure that the above prompt is written to stdout immediately you
            should call fflush(stdout) after the printf call.
            scanf("%50s",pC ustData->pszFirstName );
            printf("Enter Last Name : ");
            Similarly here too.
            scanf("%50s",pC ustData->pszLastName) ;
            >
            i want the name should not acceed 50 char,but here in this case if i
            give 52 chars for fisrt name as input it will take 50 for first name
            and rest 2 for last name.
            it doesnt allow me to enter last name.
            So what i sould do to get only 50 chars and discard rest 2 chars?
            You can use a small function that reads and discards unwanted characters
            in the input stream up to the newline character or EOF. Numerous source
            examples have been posted here. Do a search of Google Groups' archives
            of c.l.c with a search term like "discard input".

            However a better approach might be to avoid scanf altogether (since it's
            difficult to use in a water-tight manner), and read in lines one by one
            with fgets and parse them with sscanf and other functions. A fgets
            replacement for the above calls would be like:

            if (fgets(input_bu ffer, input_buffer_le ngth, stdin) == NULL) {
            /* A return of NULL means there was a problem. You can deal with
            that here.
            */
            }

            The problem of overlong input still remains. You still need to discard
            any input remaining in the stream and check that fgets has read a
            complete line. You could treat incomplete reads as either a normal
            situation or as an error. That would be program specific.

            Comment

            Working...